]>
git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blob - tests.js
2 // $ phantomjs tests.js
5 var page
= require('webpage').create();
6 var url
= 'src/index.html';
7 var testMaxTime
= 5000;
9 page
.onResourceError = function(e
) {
10 console
.log("Error loading " + e
.url
);
15 console
.log("Failed");
19 function waitForGenerate(fn
, maxTime
) {
21 maxTime
= testMaxTime
;
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
;
31 var hasFinished
= addressCount
> 0 && addressCount
== prevAddressCount
;
32 prevAddressCount
= addressCount
;
36 else if (hasTimedOut
) {
37 console
.log("Test timed out");
41 setTimeout(keepWaiting
, 100);
48 if (tests
.length
> 0) {
49 var testsStr
= tests
.length
== 1 ? "test" : "tests";
50 console
.log(tests
.length
+ " " + testsStr
+ " remaining");
54 console
.log("Finished with 0 failures");
60 * Randomize array element order in-place.
61 * Using Durstenfeld shuffle algorithm.
62 * See http://stackoverflow.com/a/12646864
64 function shuffle(array
) {
65 for (var i
= array
.length
- 1; i
> 0; i
--) {
66 var j
= Math
.floor(Math
.random() * (i
+ 1));
76 // Page loads with status of 'success'
78 page
.open(url
, function(status
) {
79 if (status
!= "success") {
80 console
.log("Page did not load with status 'success'");
89 page
.open(url
, function(status
) {
90 var content
= page
.evaluate(function() {
91 return document
.body
.textContent
.trim();
94 console
.log("Page does not have text");
101 // Entering mnemonic generates addresses
103 page
.open(url
, function(status
) {
105 page
.evaluate(function() {
106 $(".phrase").val("abandon abandon ability").trigger("input");
109 waitForGenerate(function() {
110 var addressCount
= page
.evaluate(function() {
111 return $(".address").length
;
113 if (addressCount
!= 20) {
114 console
.log("Mnemonic did not generate addresses");
115 console
.log("Expected: " + expected
);
116 console
.log("Got: " + actual
);
124 // Random button generates random mnemonic
126 page
.open(url
, function(status
) {
127 // check initial phrase is empty
128 var phrase
= page
.evaluate(function() {
129 return $(".phrase").text();
132 console
.log("Initial phrase is not blank");
135 // press the 'generate' button
136 page
.evaluate(function() {
137 $(".generate").click();
139 // get the new phrase
140 waitForGenerate(function() {
141 var phrase
= page
.evaluate(function() {
142 return $(".phrase").val();
144 if (phrase
.length
<= 0) {
145 console
.log("Phrase not generated by pressing button");
153 // Mnemonic length can be customized
155 page
.open(url
, function(status
) {
156 // set the length to 6
157 var expectedLength
= "6";
158 page
.evaluate(function() {
159 $(".strength option[selected]").removeAttr("selected");
160 $(".strength option[value=6]").prop("selected", true);
162 // press the 'generate' button
163 page
.evaluate(function() {
164 $(".generate").click();
166 // check the new phrase is six words long
167 waitForGenerate(function() {
168 var actualLength
= page
.evaluate(function() {
169 var words
= $(".phrase").val().split(" ");
172 if (actualLength
!= expectedLength
) {
173 console
.log("Phrase not generated with correct length");
174 console
.log("Expected: " + expectedLength
);
175 console
.log("Actual: " + actualLength
);
183 // Passphrase can be set
185 page
.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");
192 // check the address is generated correctly
193 waitForGenerate(function() {
194 var actual
= page
.evaluate(function() {
195 return $(".address:first").text();
197 if (actual
!= expected
) {
198 console
.log("Passphrase results in wrong address");
199 console
.log("Expected: " + expected
);
200 console
.log("Actual: " + actual
);
208 // Network can be set to bitcoin testnet
210 page
.open(url
, function(status
) {
211 // set the phrase and coin
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");
220 // check the address is generated correctly
221 waitForGenerate(function() {
222 var actual
= page
.evaluate(function() {
223 return $(".address:first").text();
225 if (actual
!= expected
) {
226 console
.log("Bitcoin testnet address is incorrect");
227 console
.log("Expected: " + expected
);
228 console
.log("Actual: " + actual
);
236 // Network can be set to litecoin
238 page
.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");
248 // check the address is generated correctly
249 waitForGenerate(function() {
250 var actual
= page
.evaluate(function() {
251 return $(".address:first").text();
253 if (actual
!= expected
) {
254 console
.log("Litecoin address is incorrect");
255 console
.log("Expected: " + expected
);
256 console
.log("Actual: " + actual
);
264 // Network can be set to dogecoin
266 page
.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");
276 // check the address is generated correctly
277 waitForGenerate(function() {
278 var actual
= page
.evaluate(function() {
279 return $(".address:first").text();
281 if (actual
!= expected
) {
282 console
.log("Dogecoin address is incorrect");
283 console
.log("Expected: " + expected
);
284 console
.log("Actual: " + actual
);
292 // Network can be set to shadowcash
294 page
.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");
304 // check the address is generated correctly
305 waitForGenerate(function() {
306 var actual
= page
.evaluate(function() {
307 return $(".address:first").text();
309 if (actual
!= expected
) {
310 console
.log("Shadowcash address is incorrect");
311 console
.log("Expected: " + expected
);
312 console
.log("Actual: " + actual
);
320 // Network can be set to shadowcash testnet
322 page
.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");
332 // check the address is generated correctly
333 waitForGenerate(function() {
334 var actual
= page
.evaluate(function() {
335 return $(".address:first").text();
337 if (actual
!= expected
) {
338 console
.log("Shadowcash testnet address is incorrect");
339 console
.log("Expected: " + expected
);
340 console
.log("Actual: " + actual
);
348 // Network can be set to viacoin
350 page
.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");
360 // check the address is generated correctly
361 waitForGenerate(function() {
362 var actual
= page
.evaluate(function() {
363 return $(".address:first").text();
365 if (actual
!= expected
) {
366 console
.log("Viacoin address is incorrect");
367 console
.log("Expected: " + expected
);
368 console
.log("Actual: " + actual
);
376 // Network can be set to viacoin testnet
378 page
.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");
388 // check the address is generated correctly
389 waitForGenerate(function() {
390 var actual
= page
.evaluate(function() {
391 return $(".address:first").text();
393 if (actual
!= expected
) {
394 console
.log("Viacoin testnet address is incorrect");
395 console
.log("Expected: " + expected
);
396 console
.log("Actual: " + actual
);
404 // Network can be set to jumbucks
406 page
.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");
416 // check the address is generated correctly
417 waitForGenerate(function() {
418 var actual
= page
.evaluate(function() {
419 return $(".address:first").text();
421 if (actual
!= expected
) {
422 console
.log("Jumbucks address is incorrect");
423 console
.log("Expected: " + expected
);
424 console
.log("Actual: " + actual
);
432 // Network can be set to clam
434 page
.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");
444 // check the address is generated correctly
445 waitForGenerate(function() {
446 var actual
= page
.evaluate(function() {
447 return $(".address:first").text();
449 if (actual
!= expected
) {
450 console
.log("CLAM address is incorrect");
451 console
.log("Expected: " + expected
);
452 console
.log("Actual: " + actual
);
460 // Network can be set to dash
462 page
.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");
472 // check the address is generated correctly
473 waitForGenerate(function() {
474 var actual
= page
.evaluate(function() {
475 return $(".address:first").text();
477 if (actual
!= expected
) {
478 console
.log("DASH address is incorrect");
479 console
.log("Expected: " + expected
);
480 console
.log("Actual: " + actual
);
488 // BIP39 seed is set from phrase
490 page
.open(url
, function(status
) {
492 var expected
= "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
493 page
.evaluate(function() {
494 $(".phrase").val("abandon abandon ability");
495 $(".phrase").trigger("input");
497 // check the address is generated correctly
498 waitForGenerate(function() {
499 var actual
= page
.evaluate(function() {
500 return $(".seed").val();
502 if (actual
!= expected
) {
503 console
.log("BIP39 seed is incorrectly generated from mnemonic");
504 console
.log("Expected: " + expected
);
505 console
.log("Actual: " + actual
);
513 // BIP32 root key is set from phrase
515 page
.open(url
, function(status
) {
517 var expected
= "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
518 page
.evaluate(function() {
519 $(".phrase").val("abandon abandon ability");
520 $(".phrase").trigger("input");
522 // check the address is generated correctly
523 waitForGenerate(function() {
524 var actual
= page
.evaluate(function() {
525 return $(".root-key").val();
527 if (actual
!= expected
) {
528 console
.log("Root key is incorrectly generated from mnemonic");
529 console
.log("Expected: " + expected
);
530 console
.log("Actual: " + actual
);
538 // Tabs show correct addresses when changed
540 page
.open(url
, function(status
) {
542 var expected
= "17uQ7s2izWPwBmEVFikTmZUjbBKWYdJchz";
543 page
.evaluate(function() {
544 $(".phrase").val("abandon abandon ability");
545 $(".phrase").trigger("input");
548 waitForGenerate(function() {
549 page
.evaluate(function() {
550 $("#bip32-tab a").click();
552 // check the address is generated correctly
553 waitForGenerate(function() {
554 var actual
= page
.evaluate(function() {
555 return $(".address:first").text();
557 if (actual
!= expected
) {
558 console
.log("Clicking tab generates incorrect address");
559 console
.log("Expected: " + expected
);
560 console
.log("Actual: " + actual
);
569 // BIP44 derivation path is shown
571 page
.open(url
, function(status
) {
573 var expected
= "m/44'/0'/0'/0";
574 page
.evaluate(function() {
575 $(".phrase").val("abandon abandon ability");
576 $(".phrase").trigger("input");
578 // check the derivation path of the first address
579 waitForGenerate(function() {
580 var actual
= page
.evaluate(function() {
581 return $("#bip44 .path").val();
583 if (actual
!= expected
) {
584 console
.log("BIP44 derivation path is incorrect");
585 console
.log("Expected: " + expected
);
586 console
.log("Actual: " + actual
);
594 // BIP44 extended private key is shown
596 page
.open(url
, function(status
) {
598 var expected
= "xprvA2DxxvPZcyRvYgZMGS53nadR32mVDeCyqQYyFhrCVbJNjPoxMeVf7QT5g7mQASbTf9Kp4cryvcXnu2qurjWKcrdsr91jXymdCDNxKgLFKJG";
599 page
.evaluate(function() {
600 $(".phrase").val("abandon abandon ability");
601 $(".phrase").trigger("input");
603 // check the BIP44 extended private key
604 waitForGenerate(function() {
605 var actual
= page
.evaluate(function() {
606 return $(".extended-priv-key").val();
608 if (actual
!= expected
) {
609 console
.log("BIP44 extended private key is incorrect");
610 console
.log("Expected: " + expected
);
611 console
.log("Actual: " + actual
);
619 // BIP44 extended public key is shown
621 page
.open(url
, function(status
) {
623 var expected
= "xpub6FDKNRvTTLzDmAdpNTc49ia9b4byd6vqCdUa46Fp3vqMcC96uBoufCmZXQLiN5AK3iSCJMhf9gT2sxkpyaPepRuA7W3MujV5tGmF5VfbueM";
624 page
.evaluate(function() {
625 $(".phrase").val("abandon abandon ability");
626 $(".phrase").trigger("input");
628 // check the BIP44 extended public key
629 waitForGenerate(function() {
630 var actual
= page
.evaluate(function() {
631 return $(".extended-pub-key").val();
633 if (actual
!= expected
) {
634 console
.log("BIP44 extended public key is incorrect");
635 console
.log("Expected: " + expected
);
636 console
.log("Actual: " + actual
);
644 // BIP44 purpose field changes address list
646 page
.open(url
, function(status
) {
648 var expected
= "1JbDzRJ2cDT8aat2xwKd6Pb2zzavow5MhF";
649 page
.evaluate(function() {
650 $(".phrase").val("abandon abandon ability");
651 $(".phrase").trigger("input");
653 waitForGenerate(function() {
654 // change the bip44 purpose field to 45
655 page
.evaluate(function() {
656 $("#bip44 .purpose").val("45");
657 $("#bip44 .purpose").trigger("input");
659 waitForGenerate(function() {
660 // check the address for the new derivation path
661 var actual
= page
.evaluate(function() {
662 return $(".address:first").text();
664 if (actual
!= expected
) {
665 console
.log("BIP44 purpose field generates incorrect address");
666 console
.log("Expected: " + expected
);
667 console
.log("Actual: " + actual
);
676 // BIP44 coin field changes address list
678 page
.open(url
, function(status
) {
680 var expected
= "1F6dB2djQYrxoyfZZmfr6D5voH8GkJTghk";
681 page
.evaluate(function() {
682 $(".phrase").val("abandon abandon ability");
683 $(".phrase").trigger("input");
685 waitForGenerate(function() {
686 // change the bip44 purpose field to 45
687 page
.evaluate(function() {
688 $("#bip44 .coin").val("1");
689 $("#bip44 .coin").trigger("input");
691 waitForGenerate(function() {
692 // check the address for the new derivation path
693 var actual
= page
.evaluate(function() {
694 return $(".address:first").text();
696 if (actual
!= expected
) {
697 console
.log("BIP44 coin field generates incorrect address");
698 console
.log("Expected: " + expected
);
699 console
.log("Actual: " + actual
);
708 // BIP44 account field changes address list
710 page
.open(url
, function(status
) {
712 var expected
= "1Nq2Wmu726XHCuGhctEtGmhxo3wzk5wZ1H";
713 page
.evaluate(function() {
714 $(".phrase").val("abandon abandon ability");
715 $(".phrase").trigger("input");
717 waitForGenerate(function() {
718 // change the bip44 purpose field to 45
719 page
.evaluate(function() {
720 $("#bip44 .account").val("1");
721 $("#bip44 .account").trigger("input");
723 waitForGenerate(function() {
724 // check the address for the new derivation path
725 var actual
= page
.evaluate(function() {
726 return $(".address:first").text();
728 if (actual
!= expected
) {
729 console
.log("BIP44 account field generates incorrect address");
730 console
.log("Expected: " + expected
);
731 console
.log("Actual: " + actual
);
740 // BIP44 change field changes address list
742 page
.open(url
, function(status
) {
744 var expected
= "1KAGfWgqfVbSSXY56fNQ7YnhyKuoskHtYo";
745 page
.evaluate(function() {
746 $(".phrase").val("abandon abandon ability");
747 $(".phrase").trigger("input");
749 waitForGenerate(function() {
750 // change the bip44 purpose field to 45
751 page
.evaluate(function() {
752 $("#bip44 .change").val("1");
753 $("#bip44 .change").trigger("input");
755 waitForGenerate(function() {
756 // check the address for the new derivation path
757 var actual
= page
.evaluate(function() {
758 return $(".address:first").text();
760 if (actual
!= expected
) {
761 console
.log("BIP44 change field generates incorrect address");
762 console
.log("Expected: " + expected
);
763 console
.log("Actual: " + actual
);
772 // BIP32 derivation path can be set
774 page
.open(url
, function(status
) {
776 var expected
= "16pYQQdLD1hH4hwTGLXBaZ9Teboi1AGL8L";
777 page
.evaluate(function() {
778 $(".phrase").val("abandon abandon ability");
779 $(".phrase").trigger("input");
782 waitForGenerate(function() {
783 page
.evaluate(function() {
784 $("#bip32-tab a").click();
786 // set the derivation path to m/1
787 waitForGenerate(function() {
788 page
.evaluate(function() {
789 $("#bip32 .path").val("m/1");
790 $("#bip32 .path").trigger("input");
792 // check the address is generated correctly
793 waitForGenerate(function() {
794 var actual
= page
.evaluate(function() {
795 return $(".address:first").text();
797 if (actual
!= expected
) {
798 console
.log("Custom BIP32 path generates incorrect address");
799 console
.log("Expected: " + expected
);
800 console
.log("Actual: " + actual
);
810 // BIP32 can use hardened derivation paths
812 page
.open(url
, function(status
) {
814 var expected
= "14aXZeprXAE3UUKQc4ihvwBvww2LuEoHo4";
815 page
.evaluate(function() {
816 $(".phrase").val("abandon abandon ability");
817 $(".phrase").trigger("input");
820 waitForGenerate(function() {
821 page
.evaluate(function() {
822 $("#bip32-tab a").click();
824 // set the derivation path to m/0'
825 waitForGenerate(function() {
826 page
.evaluate(function() {
827 $("#bip32 .path").val("m/0'");
828 $("#bip32 .path").trigger("input");
830 // check the address is generated correctly
831 waitForGenerate(function() {
832 var actual
= page
.evaluate(function() {
833 return $(".address:first").text();
835 if (actual
!= expected
) {
836 console
.log("Hardened BIP32 path generates incorrect address");
837 console
.log("Expected: " + expected
);
838 console
.log("Actual: " + actual
);
848 // BIP32 extended private key is shown
850 page
.open(url
, function(status
) {
852 var expected
= "xprv9va99uTVE5aLiutUVLTyfxfe8v8aaXjSQ1XxZbK6SezYVuikA9MnjQVTA8rQHpNA5LKvyQBpLiHbBQiiccKiBDs7eRmBogsvq3THFeLHYbe";
853 page
.evaluate(function() {
854 $(".phrase").val("abandon abandon ability");
855 $(".phrase").trigger("input");
858 waitForGenerate(function() {
859 page
.evaluate(function() {
860 $("#bip32-tab a").click();
862 // check the extended private key is generated correctly
863 waitForGenerate(function() {
864 var actual
= page
.evaluate(function() {
865 return $(".extended-priv-key").val();
867 if (actual
!= expected
) {
868 console
.log("BIP32 extended private key is incorrect");
869 console
.log("Expected: " + expected
);
870 console
.log("Actual: " + actual
);
879 // BIP32 extended public key is shown
881 page
.open(url
, function(status
) {
883 var expected
= "xpub69ZVZQzP4T8dwPxwbMzz36cNgwy4yzTHmETZMyihzzXXNi3thgg3HCow1RtY252wdw5rS8369xKnraN5Q93y3FkFfJp2XEHWUrkyXsjS93P";
884 page
.evaluate(function() {
885 $(".phrase").val("abandon abandon ability");
886 $(".phrase").trigger("input");
889 waitForGenerate(function() {
890 page
.evaluate(function() {
891 $("#bip32-tab a").click();
893 // check the extended public key is generated correctly
894 waitForGenerate(function() {
895 var actual
= page
.evaluate(function() {
896 return $(".extended-pub-key").val();
898 if (actual
!= expected
) {
899 console
.log("BIP32 extended public key is incorrect");
900 console
.log("Expected: " + expected
);
901 console
.log("Actual: " + actual
);
910 // Derivation path is shown in table
912 page
.open(url
, function(status
) {
914 var expected
= "m/44'/0'/0'/0/0";
915 page
.evaluate(function() {
916 $(".phrase").val("abandon abandon ability");
917 $(".phrase").trigger("input");
919 // check for derivation path in table
920 waitForGenerate(function() {
921 var actual
= page
.evaluate(function() {
922 return $(".index:first").text();
924 if (actual
!= expected
) {
925 console
.log("Derivation path shown incorrectly in table");
926 console
.log("Expected: " + expected
);
927 console
.log("Actual: " + actual
);
935 // Derivation path for address can be hardened
937 page
.open(url
, function(status
) {
939 var expected
= "18exLzUv7kfpiXRzmCjFDoC9qwNLFyvwyd";
940 page
.evaluate(function() {
941 $(".phrase").val("abandon abandon ability");
942 $(".phrase").trigger("input");
945 waitForGenerate(function() {
946 page
.evaluate(function() {
947 $("#bip32-tab a").click();
949 waitForGenerate(function() {
950 // select the hardened addresses option
951 page
.evaluate(function() {
952 $(".hardened-addresses").prop("checked", true);
953 $(".hardened-addresses").trigger("change");
955 waitForGenerate(function() {
956 // check the generated address is hardened
957 var actual
= page
.evaluate(function() {
958 return $(".address:first").text();
960 if (actual
!= expected
) {
961 console
.log("Hardened address is incorrect");
962 console
.log("Expected: " + expected
);
963 console
.log("Actual: " + actual
);
973 // Derivation path visibility can be toggled
975 page
.open(url
, function(status
) {
977 page
.evaluate(function() {
978 $(".phrase").val("abandon abandon ability");
979 $(".phrase").trigger("input");
981 waitForGenerate(function() {
982 // toggle path visibility
983 page
.evaluate(function() {
984 $(".index-toggle").click();
986 // check the path is not visible
987 var isInvisible
= page
.evaluate(function() {
988 return $(".index:first span").hasClass("invisible");
991 console
.log("Toggled derivation path is visible");
1001 page
.open(url
, function(status
) {
1002 var expected
= "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
1004 page
.evaluate(function() {
1005 $(".phrase").val("abandon abandon ability").trigger("input");
1008 waitForGenerate(function() {
1009 var actual
= page
.evaluate(function() {
1010 return $(".address:first").text();
1012 if (actual
!= expected
) {
1013 console
.log("Address is not shown");
1014 console
.log("Expected: " + expected
);
1015 console
.log("Got: " + actual
);
1023 // Addresses are shown in order of derivation path
1025 page
.open(url
, function(status
) {
1027 page
.evaluate(function() {
1028 $(".phrase").val("abandon abandon ability").trigger("input");
1030 // get the derivation paths
1031 waitForGenerate(function() {
1032 var paths
= page
.evaluate(function() {
1033 return $(".index").map(function(i
, e
) {
1037 if (paths
.length
!= 20) {
1038 console
.log("Total paths is less than expected: " + paths
.length
);
1041 for (var i
=0; i
<paths
.length
; i
++) {
1042 var expected
= "m/44'/0'/0'/0/" + i
;
1043 var actual
= paths
[i
];
1044 if (actual
!= expected
) {
1045 console
.log("Path " + i
+ " is incorrect");
1046 console
.log("Expected: " + expected
);
1047 console
.log("Actual: " + actual
);
1056 // Address visibility can be toggled
1058 page
.open(url
, function(status
) {
1060 page
.evaluate(function() {
1061 $(".phrase").val("abandon abandon ability");
1062 $(".phrase").trigger("input");
1064 waitForGenerate(function() {
1065 // toggle address visibility
1066 page
.evaluate(function() {
1067 $(".address-toggle").click();
1069 // check the address is not visible
1070 var isInvisible
= page
.evaluate(function() {
1071 return $(".address:first span").hasClass("invisible");
1074 console
.log("Toggled address is visible");
1082 // Private key is shown
1083 // Private key visibility can be toggled
1085 // More addresses can be generated
1086 // A custom number of additional addresses can be generated
1087 // Additional addresses are shown in order of derivation path
1089 // BIP32 root key can be set by the user
1090 // Setting BIP32 root key clears the existing phrase, passphrase and seed
1091 // Clearing of phrase, passphrase and seed can be cancelled by user
1092 // Custom BIP32 root key is used when changing the derivation path
1094 // Incorrect mnemonic shows error
1095 // Incorrect word shows suggested replacement
1096 // Incorrect BIP32 root key shows error
1097 // Derivation path not starting with m shows error
1098 // Derivation path containing invalid characters shows useful error
1100 // Github Issue 11: Default word length is 15
1101 // https://github.com/dcpos/bip39/issues/11
1103 // Github Issue 12: Generate more rows with private keys hidden
1104 // https://github.com/dcpos/bip39/issues/12
1106 // Github Issue 19: Mnemonic is not sensitive to whitespace
1107 // https://github.com/dcpos/bip39/issues/19
1109 // Github Issue 23: Use correct derivation path when changing tabs
1110 // https://github.com/dcpos/bip39/issues/23
1112 // Github Issue 26: When using a Root key derrived altcoins are incorrect
1113 // https://github.com/dcpos/bip39/issues/26
1117 console
.log("Running tests...");
1118 tests
= shuffle(tests
);