]>
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);
47 function waitForFeedback(fn
, maxTime
) {
49 maxTime
= testMaxTime
;
51 var start
= new Date().getTime();
52 var wait
= function keepWaiting() {
53 var now
= new Date().getTime();
54 var hasTimedOut
= now
- start
> maxTime
;
56 console
.log("Test timed out");
60 var feedback
= page
.evaluate(function() {
61 var feedback
= $(".feedback");
62 if (feedback
.css("display") == "none") {
65 return feedback
.text();
67 var hasFinished
= feedback
.length
> 0 && feedback
!= "Calculating...";
72 setTimeout(keepWaiting
, 100);
79 if (tests
.length
> 0) {
80 var testsStr
= tests
.length
== 1 ? "test" : "tests";
81 console
.log(tests
.length
+ " " + testsStr
+ " remaining");
85 console
.log("Finished with 0 failures");
91 * Randomize array element order in-place.
92 * Using Durstenfeld shuffle algorithm.
93 * See http://stackoverflow.com/a/12646864
95 function shuffle(array
) {
96 for (var i
= array
.length
- 1; i
> 0; i
--) {
97 var j
= Math
.floor(Math
.random() * (i
+ 1));
107 // Page loads with status of 'success'
109 page
.open(url
, function(status
) {
110 if (status
!= "success") {
111 console
.log("Page did not load with status 'success'");
120 page
.open(url
, function(status
) {
121 var content
= page
.evaluate(function() {
122 return document
.body
.textContent
.trim();
125 console
.log("Page does not have text");
132 // Entering mnemonic generates addresses
134 page
.open(url
, function(status
) {
136 page
.evaluate(function() {
137 $(".phrase").val("abandon abandon ability").trigger("input");
140 waitForGenerate(function() {
141 var addressCount
= page
.evaluate(function() {
142 return $(".address").length
;
144 if (addressCount
!= 20) {
145 console
.log("Mnemonic did not generate addresses");
146 console
.log("Expected: " + expected
);
147 console
.log("Got: " + actual
);
155 // Random button generates random mnemonic
157 page
.open(url
, function(status
) {
158 // check initial phrase is empty
159 var phrase
= page
.evaluate(function() {
160 return $(".phrase").text();
163 console
.log("Initial phrase is not blank");
166 // press the 'generate' button
167 page
.evaluate(function() {
168 $(".generate").click();
170 // get the new phrase
171 waitForGenerate(function() {
172 var phrase
= page
.evaluate(function() {
173 return $(".phrase").val();
175 if (phrase
.length
<= 0) {
176 console
.log("Phrase not generated by pressing button");
184 // Mnemonic length can be customized
186 page
.open(url
, function(status
) {
187 // set the length to 6
188 var expectedLength
= "6";
189 page
.evaluate(function() {
190 $(".strength option[selected]").removeAttr("selected");
191 $(".strength option[value=6]").prop("selected", true);
193 // press the 'generate' button
194 page
.evaluate(function() {
195 $(".generate").click();
197 // check the new phrase is six words long
198 waitForGenerate(function() {
199 var actualLength
= page
.evaluate(function() {
200 var words
= $(".phrase").val().split(" ");
203 if (actualLength
!= expectedLength
) {
204 console
.log("Phrase not generated with correct length");
205 console
.log("Expected: " + expectedLength
);
206 console
.log("Actual: " + actualLength
);
214 // Passphrase can be set
216 page
.open(url
, function(status
) {
217 // set the phrase and passphrase
218 var expected
= "15pJzUWPGzR7avffV9nY5by4PSgSKG9rba";
219 page
.evaluate(function() {
220 $(".phrase").val("abandon abandon ability");
221 $(".passphrase").val("secure_passphrase").trigger("input");
223 // check the address is generated correctly
224 waitForGenerate(function() {
225 var actual
= page
.evaluate(function() {
226 return $(".address:first").text();
228 if (actual
!= expected
) {
229 console
.log("Passphrase results in wrong address");
230 console
.log("Expected: " + expected
);
231 console
.log("Actual: " + actual
);
239 // Network can be set to bitcoin testnet
241 page
.open(url
, function(status
) {
242 // set the phrase and coin
243 var expected
= "mucaU5iiDaJDb69BHLeDv8JFfGiyg2nJKi";
244 page
.evaluate(function() {
245 $(".phrase").val("abandon abandon ability");
246 $(".phrase").trigger("input");
247 $(".network option[selected]").removeAttr("selected");
248 $(".network option[value=1]").prop("selected", true);
249 $(".network").trigger("change");
251 // check the address is generated correctly
252 waitForGenerate(function() {
253 var actual
= page
.evaluate(function() {
254 return $(".address:first").text();
256 if (actual
!= expected
) {
257 console
.log("Bitcoin testnet address is incorrect");
258 console
.log("Expected: " + expected
);
259 console
.log("Actual: " + actual
);
267 // Network can be set to litecoin
269 page
.open(url
, function(status
) {
270 // set the phrase and coin
271 var expected
= "LQ4XU8RX2ULPmPq9FcUHdVmPVchP9nwXdn";
272 page
.evaluate(function() {
273 $(".phrase").val("abandon abandon ability");
274 $(".phrase").trigger("input");
275 $(".network option[selected]").removeAttr("selected");
276 $(".network option[value=2]").prop("selected", true);
277 $(".network").trigger("change");
279 // check the address is generated correctly
280 waitForGenerate(function() {
281 var actual
= page
.evaluate(function() {
282 return $(".address:first").text();
284 if (actual
!= expected
) {
285 console
.log("Litecoin address is incorrect");
286 console
.log("Expected: " + expected
);
287 console
.log("Actual: " + actual
);
295 // Network can be set to dogecoin
297 page
.open(url
, function(status
) {
298 // set the phrase and coin
299 var expected
= "DPQH2AtuzkVSG6ovjKk4jbUmZ6iXLpgbJA";
300 page
.evaluate(function() {
301 $(".phrase").val("abandon abandon ability");
302 $(".phrase").trigger("input");
303 $(".network option[selected]").removeAttr("selected");
304 $(".network option[value=3]").prop("selected", true);
305 $(".network").trigger("change");
307 // check the address is generated correctly
308 waitForGenerate(function() {
309 var actual
= page
.evaluate(function() {
310 return $(".address:first").text();
312 if (actual
!= expected
) {
313 console
.log("Dogecoin address is incorrect");
314 console
.log("Expected: " + expected
);
315 console
.log("Actual: " + actual
);
323 // Network can be set to shadowcash
325 page
.open(url
, function(status
) {
326 // set the phrase and coin
327 var expected
= "SiSZtfYAXEFvMm3XM8hmtkGDyViRwErtCG";
328 page
.evaluate(function() {
329 $(".phrase").val("abandon abandon ability");
330 $(".phrase").trigger("input");
331 $(".network option[selected]").removeAttr("selected");
332 $(".network option[value=4]").prop("selected", true);
333 $(".network").trigger("change");
335 // check the address is generated correctly
336 waitForGenerate(function() {
337 var actual
= page
.evaluate(function() {
338 return $(".address:first").text();
340 if (actual
!= expected
) {
341 console
.log("Shadowcash address is incorrect");
342 console
.log("Expected: " + expected
);
343 console
.log("Actual: " + actual
);
351 // Network can be set to shadowcash testnet
353 page
.open(url
, function(status
) {
354 // set the phrase and coin
355 var expected
= "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
356 page
.evaluate(function() {
357 $(".phrase").val("abandon abandon ability");
358 $(".phrase").trigger("input");
359 $(".network option[selected]").removeAttr("selected");
360 $(".network option[value=5]").prop("selected", true);
361 $(".network").trigger("change");
363 // check the address is generated correctly
364 waitForGenerate(function() {
365 var actual
= page
.evaluate(function() {
366 return $(".address:first").text();
368 if (actual
!= expected
) {
369 console
.log("Shadowcash testnet address is incorrect");
370 console
.log("Expected: " + expected
);
371 console
.log("Actual: " + actual
);
379 // Network can be set to viacoin
381 page
.open(url
, function(status
) {
382 // set the phrase and coin
383 var expected
= "Vq9Eq4N5SQnjqZvxtxzo7hZPW5XnyJsmXT";
384 page
.evaluate(function() {
385 $(".phrase").val("abandon abandon ability");
386 $(".phrase").trigger("input");
387 $(".network option[selected]").removeAttr("selected");
388 $(".network option[value=6]").prop("selected", true);
389 $(".network").trigger("change");
391 // check the address is generated correctly
392 waitForGenerate(function() {
393 var actual
= page
.evaluate(function() {
394 return $(".address:first").text();
396 if (actual
!= expected
) {
397 console
.log("Viacoin address is incorrect");
398 console
.log("Expected: " + expected
);
399 console
.log("Actual: " + actual
);
407 // Network can be set to viacoin testnet
409 page
.open(url
, function(status
) {
410 // set the phrase and coin
411 var expected
= "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
412 page
.evaluate(function() {
413 $(".phrase").val("abandon abandon ability");
414 $(".phrase").trigger("input");
415 $(".network option[selected]").removeAttr("selected");
416 $(".network option[value=7]").prop("selected", true);
417 $(".network").trigger("change");
419 // check the address is generated correctly
420 waitForGenerate(function() {
421 var actual
= page
.evaluate(function() {
422 return $(".address:first").text();
424 if (actual
!= expected
) {
425 console
.log("Viacoin testnet address is incorrect");
426 console
.log("Expected: " + expected
);
427 console
.log("Actual: " + actual
);
435 // Network can be set to jumbucks
437 page
.open(url
, function(status
) {
438 // set the phrase and coin
439 var expected
= "JLEXccwDXADK4RxBPkRez7mqsHVoJBEUew";
440 page
.evaluate(function() {
441 $(".phrase").val("abandon abandon ability");
442 $(".phrase").trigger("input");
443 $(".network option[selected]").removeAttr("selected");
444 $(".network option[value=8]").prop("selected", true);
445 $(".network").trigger("change");
447 // check the address is generated correctly
448 waitForGenerate(function() {
449 var actual
= page
.evaluate(function() {
450 return $(".address:first").text();
452 if (actual
!= expected
) {
453 console
.log("Jumbucks address is incorrect");
454 console
.log("Expected: " + expected
);
455 console
.log("Actual: " + actual
);
463 // Network can be set to clam
465 page
.open(url
, function(status
) {
466 // set the phrase and coin
467 var expected
= "xCp4sakjVx4pUAZ6cBCtuin8Ddb6U1sk9y";
468 page
.evaluate(function() {
469 $(".phrase").val("abandon abandon ability");
470 $(".phrase").trigger("input");
471 $(".network option[selected]").removeAttr("selected");
472 $(".network option[value=9]").prop("selected", true);
473 $(".network").trigger("change");
475 // check the address is generated correctly
476 waitForGenerate(function() {
477 var actual
= page
.evaluate(function() {
478 return $(".address:first").text();
480 if (actual
!= expected
) {
481 console
.log("CLAM address is incorrect");
482 console
.log("Expected: " + expected
);
483 console
.log("Actual: " + actual
);
491 // Network can be set to dash
493 page
.open(url
, function(status
) {
494 // set the phrase and coin
495 var expected
= "XdbhtMuGsPSkE6bPdNTHoFSszQKmK4S5LT";
496 page
.evaluate(function() {
497 $(".phrase").val("abandon abandon ability");
498 $(".phrase").trigger("input");
499 $(".network option[selected]").removeAttr("selected");
500 $(".network option[value=10]").prop("selected", true);
501 $(".network").trigger("change");
503 // check the address is generated correctly
504 waitForGenerate(function() {
505 var actual
= page
.evaluate(function() {
506 return $(".address:first").text();
508 if (actual
!= expected
) {
509 console
.log("DASH address is incorrect");
510 console
.log("Expected: " + expected
);
511 console
.log("Actual: " + actual
);
519 // Network can be set to namecoin
521 page
.open(url
, function(status
) {
522 // set the phrase and coin
523 var expected
= "Mw2vK2Bvex1yYtYF6sfbEg2YGoUc98YUD2";
524 page
.evaluate(function() {
525 $(".phrase").val("abandon abandon ability");
526 $(".phrase").trigger("input");
527 $(".network option[selected]").removeAttr("selected");
528 $(".network option[value=11]").prop("selected", true);
529 $(".network").trigger("change");
531 // check the address is generated correctly
532 waitForGenerate(function() {
533 var actual
= page
.evaluate(function() {
534 return $(".address:first").text();
536 if (actual
!= expected
) {
537 console
.log("Namecoin address is incorrect");
538 console
.log("Expected: " + expected
);
539 console
.log("Actual: " + actual
);
547 // Network can be set to peercoin
549 page
.open(url
, function(status
) {
550 // set the phrase and coin
551 var expected
= "PVAiioTaK2eDHSEo3tppT9AVdBYqxRTBAm";
552 page
.evaluate(function() {
553 $(".phrase").val("abandon abandon ability");
554 $(".phrase").trigger("input");
555 $(".network option[selected]").removeAttr("selected");
556 $(".network option[value=12]").prop("selected", true);
557 $(".network").trigger("change");
559 // check the address is generated correctly
560 waitForGenerate(function() {
561 var actual
= page
.evaluate(function() {
562 return $(".address:first").text();
564 if (actual
!= expected
) {
565 console
.log("Peercoin address is incorrect");
566 console
.log("Expected: " + expected
);
567 console
.log("Actual: " + actual
);
575 // BIP39 seed is set from phrase
577 page
.open(url
, function(status
) {
579 var expected
= "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
580 page
.evaluate(function() {
581 $(".phrase").val("abandon abandon ability");
582 $(".phrase").trigger("input");
584 // check the address is generated correctly
585 waitForGenerate(function() {
586 var actual
= page
.evaluate(function() {
587 return $(".seed").val();
589 if (actual
!= expected
) {
590 console
.log("BIP39 seed is incorrectly generated from mnemonic");
591 console
.log("Expected: " + expected
);
592 console
.log("Actual: " + actual
);
600 // BIP32 root key is set from phrase
602 page
.open(url
, function(status
) {
604 var expected
= "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
605 page
.evaluate(function() {
606 $(".phrase").val("abandon abandon ability");
607 $(".phrase").trigger("input");
609 // check the address is generated correctly
610 waitForGenerate(function() {
611 var actual
= page
.evaluate(function() {
612 return $(".root-key").val();
614 if (actual
!= expected
) {
615 console
.log("Root key is incorrectly generated from mnemonic");
616 console
.log("Expected: " + expected
);
617 console
.log("Actual: " + actual
);
625 // Tabs show correct addresses when changed
627 page
.open(url
, function(status
) {
629 var expected
= "17uQ7s2izWPwBmEVFikTmZUjbBKWYdJchz";
630 page
.evaluate(function() {
631 $(".phrase").val("abandon abandon ability");
632 $(".phrase").trigger("input");
635 waitForGenerate(function() {
636 page
.evaluate(function() {
637 $("#bip32-tab a").click();
639 // check the address is generated correctly
640 waitForGenerate(function() {
641 var actual
= page
.evaluate(function() {
642 return $(".address:first").text();
644 if (actual
!= expected
) {
645 console
.log("Clicking tab generates incorrect address");
646 console
.log("Expected: " + expected
);
647 console
.log("Actual: " + actual
);
656 // BIP44 derivation path is shown
658 page
.open(url
, function(status
) {
660 var expected
= "m/44'/0'/0'/0";
661 page
.evaluate(function() {
662 $(".phrase").val("abandon abandon ability");
663 $(".phrase").trigger("input");
665 // check the derivation path of the first address
666 waitForGenerate(function() {
667 var actual
= page
.evaluate(function() {
668 return $("#bip44 .path").val();
670 if (actual
!= expected
) {
671 console
.log("BIP44 derivation path is incorrect");
672 console
.log("Expected: " + expected
);
673 console
.log("Actual: " + actual
);
681 // BIP44 extended private key is shown
683 page
.open(url
, function(status
) {
685 var expected
= "xprvA2DxxvPZcyRvYgZMGS53nadR32mVDeCyqQYyFhrCVbJNjPoxMeVf7QT5g7mQASbTf9Kp4cryvcXnu2qurjWKcrdsr91jXymdCDNxKgLFKJG";
686 page
.evaluate(function() {
687 $(".phrase").val("abandon abandon ability");
688 $(".phrase").trigger("input");
690 // check the BIP44 extended private key
691 waitForGenerate(function() {
692 var actual
= page
.evaluate(function() {
693 return $(".extended-priv-key").val();
695 if (actual
!= expected
) {
696 console
.log("BIP44 extended private key is incorrect");
697 console
.log("Expected: " + expected
);
698 console
.log("Actual: " + actual
);
706 // BIP44 extended public key is shown
708 page
.open(url
, function(status
) {
710 var expected
= "xpub6FDKNRvTTLzDmAdpNTc49ia9b4byd6vqCdUa46Fp3vqMcC96uBoufCmZXQLiN5AK3iSCJMhf9gT2sxkpyaPepRuA7W3MujV5tGmF5VfbueM";
711 page
.evaluate(function() {
712 $(".phrase").val("abandon abandon ability");
713 $(".phrase").trigger("input");
715 // check the BIP44 extended public key
716 waitForGenerate(function() {
717 var actual
= page
.evaluate(function() {
718 return $(".extended-pub-key").val();
720 if (actual
!= expected
) {
721 console
.log("BIP44 extended public key is incorrect");
722 console
.log("Expected: " + expected
);
723 console
.log("Actual: " + actual
);
731 // BIP44 purpose field changes address list
733 page
.open(url
, function(status
) {
735 var expected
= "1JbDzRJ2cDT8aat2xwKd6Pb2zzavow5MhF";
736 page
.evaluate(function() {
737 $(".phrase").val("abandon abandon ability");
738 $(".phrase").trigger("input");
740 waitForGenerate(function() {
741 // change the bip44 purpose field to 45
742 page
.evaluate(function() {
743 $("#bip44 .purpose").val("45");
744 $("#bip44 .purpose").trigger("input");
746 waitForGenerate(function() {
747 // check the address for the new derivation path
748 var actual
= page
.evaluate(function() {
749 return $(".address:first").text();
751 if (actual
!= expected
) {
752 console
.log("BIP44 purpose field generates incorrect address");
753 console
.log("Expected: " + expected
);
754 console
.log("Actual: " + actual
);
763 // BIP44 coin field changes address list
765 page
.open(url
, function(status
) {
767 var expected
= "1F6dB2djQYrxoyfZZmfr6D5voH8GkJTghk";
768 page
.evaluate(function() {
769 $(".phrase").val("abandon abandon ability");
770 $(".phrase").trigger("input");
772 waitForGenerate(function() {
773 // change the bip44 purpose field to 45
774 page
.evaluate(function() {
775 $("#bip44 .coin").val("1");
776 $("#bip44 .coin").trigger("input");
778 waitForGenerate(function() {
779 // check the address for the new derivation path
780 var actual
= page
.evaluate(function() {
781 return $(".address:first").text();
783 if (actual
!= expected
) {
784 console
.log("BIP44 coin field generates incorrect address");
785 console
.log("Expected: " + expected
);
786 console
.log("Actual: " + actual
);
795 // BIP44 account field changes address list
797 page
.open(url
, function(status
) {
799 var expected
= "1Nq2Wmu726XHCuGhctEtGmhxo3wzk5wZ1H";
800 page
.evaluate(function() {
801 $(".phrase").val("abandon abandon ability");
802 $(".phrase").trigger("input");
804 waitForGenerate(function() {
805 // change the bip44 purpose field to 45
806 page
.evaluate(function() {
807 $("#bip44 .account").val("1");
808 $("#bip44 .account").trigger("input");
810 waitForGenerate(function() {
811 // check the address for the new derivation path
812 var actual
= page
.evaluate(function() {
813 return $(".address:first").text();
815 if (actual
!= expected
) {
816 console
.log("BIP44 account field generates incorrect address");
817 console
.log("Expected: " + expected
);
818 console
.log("Actual: " + actual
);
827 // BIP44 change field changes address list
829 page
.open(url
, function(status
) {
831 var expected
= "1KAGfWgqfVbSSXY56fNQ7YnhyKuoskHtYo";
832 page
.evaluate(function() {
833 $(".phrase").val("abandon abandon ability");
834 $(".phrase").trigger("input");
836 waitForGenerate(function() {
837 // change the bip44 purpose field to 45
838 page
.evaluate(function() {
839 $("#bip44 .change").val("1");
840 $("#bip44 .change").trigger("input");
842 waitForGenerate(function() {
843 // check the address for the new derivation path
844 var actual
= page
.evaluate(function() {
845 return $(".address:first").text();
847 if (actual
!= expected
) {
848 console
.log("BIP44 change field generates incorrect address");
849 console
.log("Expected: " + expected
);
850 console
.log("Actual: " + actual
);
859 // BIP32 derivation path can be set
861 page
.open(url
, function(status
) {
863 var expected
= "16pYQQdLD1hH4hwTGLXBaZ9Teboi1AGL8L";
864 page
.evaluate(function() {
865 $(".phrase").val("abandon abandon ability");
866 $(".phrase").trigger("input");
869 waitForGenerate(function() {
870 page
.evaluate(function() {
871 $("#bip32-tab a").click();
873 // set the derivation path to m/1
874 waitForGenerate(function() {
875 page
.evaluate(function() {
876 $("#bip32 .path").val("m/1");
877 $("#bip32 .path").trigger("input");
879 // check the address is generated correctly
880 waitForGenerate(function() {
881 var actual
= page
.evaluate(function() {
882 return $(".address:first").text();
884 if (actual
!= expected
) {
885 console
.log("Custom BIP32 path generates incorrect address");
886 console
.log("Expected: " + expected
);
887 console
.log("Actual: " + actual
);
897 // BIP32 can use hardened derivation paths
899 page
.open(url
, function(status
) {
901 var expected
= "14aXZeprXAE3UUKQc4ihvwBvww2LuEoHo4";
902 page
.evaluate(function() {
903 $(".phrase").val("abandon abandon ability");
904 $(".phrase").trigger("input");
907 waitForGenerate(function() {
908 page
.evaluate(function() {
909 $("#bip32-tab a").click();
911 // set the derivation path to m/0'
912 waitForGenerate(function() {
913 page
.evaluate(function() {
914 $("#bip32 .path").val("m/0'");
915 $("#bip32 .path").trigger("input");
917 // check the address is generated correctly
918 waitForGenerate(function() {
919 var actual
= page
.evaluate(function() {
920 return $(".address:first").text();
922 if (actual
!= expected
) {
923 console
.log("Hardened BIP32 path generates incorrect address");
924 console
.log("Expected: " + expected
);
925 console
.log("Actual: " + actual
);
935 // BIP32 extended private key is shown
937 page
.open(url
, function(status
) {
939 var expected
= "xprv9va99uTVE5aLiutUVLTyfxfe8v8aaXjSQ1XxZbK6SezYVuikA9MnjQVTA8rQHpNA5LKvyQBpLiHbBQiiccKiBDs7eRmBogsvq3THFeLHYbe";
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 // check the extended private key is generated correctly
950 waitForGenerate(function() {
951 var actual
= page
.evaluate(function() {
952 return $(".extended-priv-key").val();
954 if (actual
!= expected
) {
955 console
.log("BIP32 extended private key is incorrect");
956 console
.log("Expected: " + expected
);
957 console
.log("Actual: " + actual
);
966 // BIP32 extended public key is shown
968 page
.open(url
, function(status
) {
970 var expected
= "xpub69ZVZQzP4T8dwPxwbMzz36cNgwy4yzTHmETZMyihzzXXNi3thgg3HCow1RtY252wdw5rS8369xKnraN5Q93y3FkFfJp2XEHWUrkyXsjS93P";
971 page
.evaluate(function() {
972 $(".phrase").val("abandon abandon ability");
973 $(".phrase").trigger("input");
976 waitForGenerate(function() {
977 page
.evaluate(function() {
978 $("#bip32-tab a").click();
980 // check the extended public key is generated correctly
981 waitForGenerate(function() {
982 var actual
= page
.evaluate(function() {
983 return $(".extended-pub-key").val();
985 if (actual
!= expected
) {
986 console
.log("BIP32 extended public key is incorrect");
987 console
.log("Expected: " + expected
);
988 console
.log("Actual: " + actual
);
997 // Derivation path is shown in table
999 page
.open(url
, function(status
) {
1001 var expected
= "m/44'/0'/0'/0/0";
1002 page
.evaluate(function() {
1003 $(".phrase").val("abandon abandon ability");
1004 $(".phrase").trigger("input");
1006 // check for derivation path in table
1007 waitForGenerate(function() {
1008 var actual
= page
.evaluate(function() {
1009 return $(".index:first").text();
1011 if (actual
!= expected
) {
1012 console
.log("Derivation path shown incorrectly in table");
1013 console
.log("Expected: " + expected
);
1014 console
.log("Actual: " + actual
);
1022 // Derivation path for address can be hardened
1024 page
.open(url
, function(status
) {
1026 var expected
= "18exLzUv7kfpiXRzmCjFDoC9qwNLFyvwyd";
1027 page
.evaluate(function() {
1028 $(".phrase").val("abandon abandon ability");
1029 $(".phrase").trigger("input");
1032 waitForGenerate(function() {
1033 page
.evaluate(function() {
1034 $("#bip32-tab a").click();
1036 waitForGenerate(function() {
1037 // select the hardened addresses option
1038 page
.evaluate(function() {
1039 $(".hardened-addresses").prop("checked", true);
1040 $(".hardened-addresses").trigger("change");
1042 waitForGenerate(function() {
1043 // check the generated address is hardened
1044 var actual
= page
.evaluate(function() {
1045 return $(".address:first").text();
1047 if (actual
!= expected
) {
1048 console
.log("Hardened address is incorrect");
1049 console
.log("Expected: " + expected
);
1050 console
.log("Actual: " + actual
);
1060 // Derivation path visibility can be toggled
1062 page
.open(url
, function(status
) {
1064 page
.evaluate(function() {
1065 $(".phrase").val("abandon abandon ability");
1066 $(".phrase").trigger("input");
1068 waitForGenerate(function() {
1069 // toggle path visibility
1070 page
.evaluate(function() {
1071 $(".index-toggle").click();
1073 // check the path is not visible
1074 var isInvisible
= page
.evaluate(function() {
1075 return $(".index:first span").hasClass("invisible");
1078 console
.log("Toggled derivation path is visible");
1088 page
.open(url
, function(status
) {
1089 var expected
= "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
1091 page
.evaluate(function() {
1092 $(".phrase").val("abandon abandon ability").trigger("input");
1095 waitForGenerate(function() {
1096 var actual
= page
.evaluate(function() {
1097 return $(".address:first").text();
1099 if (actual
!= expected
) {
1100 console
.log("Address is not shown");
1101 console
.log("Expected: " + expected
);
1102 console
.log("Got: " + actual
);
1110 // Addresses are shown in order of derivation path
1112 page
.open(url
, function(status
) {
1114 page
.evaluate(function() {
1115 $(".phrase").val("abandon abandon ability").trigger("input");
1117 // get the derivation paths
1118 waitForGenerate(function() {
1119 var paths
= page
.evaluate(function() {
1120 return $(".index").map(function(i
, e
) {
1124 if (paths
.length
!= 20) {
1125 console
.log("Total paths is less than expected: " + paths
.length
);
1128 for (var i
=0; i
<paths
.length
; i
++) {
1129 var expected
= "m/44'/0'/0'/0/" + i
;
1130 var actual
= paths
[i
];
1131 if (actual
!= expected
) {
1132 console
.log("Path " + i
+ " is incorrect");
1133 console
.log("Expected: " + expected
);
1134 console
.log("Actual: " + actual
);
1143 // Address visibility can be toggled
1145 page
.open(url
, function(status
) {
1147 page
.evaluate(function() {
1148 $(".phrase").val("abandon abandon ability");
1149 $(".phrase").trigger("input");
1151 waitForGenerate(function() {
1152 // toggle address visibility
1153 page
.evaluate(function() {
1154 $(".address-toggle").click();
1156 // check the address is not visible
1157 var isInvisible
= page
.evaluate(function() {
1158 return $(".address:first span").hasClass("invisible");
1161 console
.log("Toggled address is visible");
1169 // Private key is shown
1171 page
.open(url
, function(status
) {
1172 var expected
= "L26cVSpWFkJ6aQkPkKmTzLqTdLJ923e6CzrVh9cmx21QHsoUmrEE";
1174 page
.evaluate(function() {
1175 $(".phrase").val("abandon abandon ability").trigger("input");
1178 waitForGenerate(function() {
1179 var actual
= page
.evaluate(function() {
1180 return $(".privkey:first").text();
1182 if (actual
!= expected
) {
1183 console
.log("Private key is not shown");
1184 console
.log("Expected: " + expected
);
1185 console
.log("Got: " + actual
);
1193 // Private key visibility can be toggled
1195 page
.open(url
, function(status
) {
1197 page
.evaluate(function() {
1198 $(".phrase").val("abandon abandon ability");
1199 $(".phrase").trigger("input");
1201 waitForGenerate(function() {
1202 // toggle private key visibility
1203 page
.evaluate(function() {
1204 $(".private-key-toggle").click();
1206 // check the private key is not visible
1207 var isInvisible
= page
.evaluate(function() {
1208 return $(".privkey:first span").hasClass("invisible");
1211 console
.log("Toggled private key is visible");
1219 // More addresses can be generated
1221 page
.open(url
, function(status
) {
1223 page
.evaluate(function() {
1224 $(".phrase").val("abandon abandon ability");
1225 $(".phrase").trigger("input");
1227 waitForGenerate(function() {
1228 // generate more addresses
1229 page
.evaluate(function() {
1232 waitForGenerate(function() {
1233 // check there are more addresses
1234 var addressCount
= page
.evaluate(function() {
1235 return $(".address").length
;
1237 if (addressCount
!= 40) {
1238 console
.log("More addresses cannot be generated");
1247 // A custom number of additional addresses can be generated
1249 page
.open(url
, function(status
) {
1251 page
.evaluate(function() {
1252 $(".phrase").val("abandon abandon ability");
1253 $(".phrase").trigger("input");
1255 waitForGenerate(function() {
1256 // get the current number of addresses
1257 var oldAddressCount
= page
.evaluate(function() {
1258 return $(".address").length
;
1260 // set a custom number of additional addresses
1261 page
.evaluate(function() {
1262 $(".rows-to-add").val(1);
1264 // generate more addresses
1265 page
.evaluate(function() {
1268 waitForGenerate(function() {
1269 // check there are the correct number of addresses
1270 var newAddressCount
= page
.evaluate(function() {
1271 return $(".address").length
;
1273 if (newAddressCount
- oldAddressCount
!= 1) {
1274 console
.log("Number of additional addresses cannot be customized");
1275 console
.log(newAddressCount
)
1276 console
.log(oldAddressCount
)
1285 // Additional addresses are shown in order of derivation path
1287 page
.open(url
, function(status
) {
1289 page
.evaluate(function() {
1290 $(".phrase").val("abandon abandon ability").trigger("input");
1292 waitForGenerate(function() {
1293 // generate more addresses
1294 page
.evaluate(function() {
1297 // get the derivation paths
1298 waitForGenerate(function() {
1299 var paths
= page
.evaluate(function() {
1300 return $(".index").map(function(i
, e
) {
1304 if (paths
.length
!= 40) {
1305 console
.log("Total additional paths is less than expected: " + paths
.length
);
1308 for (var i
=0; i
<paths
.length
; i
++) {
1309 var expected
= "m/44'/0'/0'/0/" + i
;
1310 var actual
= paths
[i
];
1311 if (actual
!= expected
) {
1312 console
.log("Path " + i
+ " is not in correct order");
1313 console
.log("Expected: " + expected
);
1314 console
.log("Actual: " + actual
);
1324 // BIP32 root key can be set by the user
1326 page
.open(url
, function(status
) {
1327 var expected
= "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
1329 page
.evaluate(function() {
1330 $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi").trigger("input");
1332 waitForGenerate(function() {
1333 var actual
= page
.evaluate(function() {
1334 return $(".address:first").text();
1336 if (actual
!= expected
) {
1337 console
.log("Setting BIP32 root key results in wrong address");
1338 console
.log("Expected: " + expected
);
1339 console
.log("Actual: " + actual
);
1347 // Setting BIP32 root key clears the existing phrase, passphrase and seed
1349 page
.open(url
, function(status
) {
1352 page
.evaluate(function() {
1353 $(".phrase").val("A non-blank but invalid value");
1355 // Accept any confirm dialogs
1356 page
.onConfirm = function() {
1360 page
.evaluate(function() {
1361 $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi").trigger("input");
1363 waitForGenerate(function() {
1364 var actual
= page
.evaluate(function() {
1365 return $(".phrase").val();
1367 if (actual
!= expected
) {
1368 console
.log("Phrase not cleared when setting BIP32 root key");
1369 console
.log("Expected: " + expected
);
1370 console
.log("Actual: " + actual
);
1378 // Clearing of phrase, passphrase and seed can be cancelled by user
1380 page
.open(url
, function(status
) {
1381 var expected
= "abandon abandon ability";
1383 page
.evaluate(function() {
1384 $(".phrase").val("abandon abandon ability");
1386 // Cancel any confirm dialogs
1387 page
.onConfirm = function() {
1391 page
.evaluate(function() {
1392 $(".root-key").val("xprv9s21ZrQH143K3d3vzEDD3KpSKmxsZ3y7CqhAL1tinwtP6wqK4TKEKjpBuo6P2hUhB6ZENo7TTSRytiP857hBZVpBdk8PooFuRspE1eywwNZ").trigger("input");
1394 var actual
= page
.evaluate(function() {
1395 return $(".phrase").val();
1397 if (actual
!= expected
) {
1398 console
.log("Phrase not retained when cancelling changes to BIP32 root key");
1399 console
.log("Expected: " + expected
);
1400 console
.log("Actual: " + actual
);
1407 // Custom BIP32 root key is used when changing the derivation path
1409 page
.open(url
, function(status
) {
1410 var expected
= "1Nq2Wmu726XHCuGhctEtGmhxo3wzk5wZ1H";
1412 page
.evaluate(function() {
1413 $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi").trigger("input");
1415 waitForGenerate(function() {
1416 // change the derivation path
1417 page
.evaluate(function() {
1418 $("#account").val("1").trigger("input");
1420 // check the bip32 root key is used for derivation, not the blank phrase
1421 waitForGenerate(function() {
1422 var actual
= page
.evaluate(function() {
1423 return $(".address:first").text();
1425 if (actual
!= expected
) {
1426 console
.log("Changing the derivation path does not use BIP32 root key");
1427 console
.log("Expected: " + expected
);
1428 console
.log("Actual: " + actual
);
1437 // Incorrect mnemonic shows error
1439 page
.open(url
, function(status
) {
1441 page
.evaluate(function() {
1442 $(".phrase").val("abandon abandon abandon").trigger("input");
1444 waitForFeedback(function() {
1445 // check there is an error shown
1446 var feedback
= page
.evaluate(function() {
1447 return $(".feedback").text();
1449 if (feedback
.length
<= 0) {
1450 console
.log("Invalid mnemonic does not show error");
1458 // Incorrect word shows suggested replacement
1460 page
.open(url
, function(status
) {
1462 page
.evaluate(function() {
1463 $(".phrase").val("abandon abandon abiliti").trigger("input");
1465 // check there is a suggestion shown
1466 waitForFeedback(function() {
1467 var feedback
= page
.evaluate(function() {
1468 return $(".feedback").text();
1470 if (feedback
.indexOf("did you mean ability?") < 0) {
1471 console
.log("Incorrect word does not show suggested replacement");
1472 console
.log("Error: " + error
);
1480 // Incorrect BIP32 root key shows error
1482 page
.open(url
, function(status
) {
1484 page
.evaluate(function() {
1485 $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpj").trigger("input");
1487 // check there is an error shown
1488 waitForFeedback(function() {
1489 var feedback
= page
.evaluate(function() {
1490 return $(".feedback").text();
1492 if (feedback
!= "Invalid root key") {
1493 console
.log("Invalid root key does not show error");
1494 console
.log("Error: " + error
);
1502 // Derivation path not starting with m shows error
1504 page
.open(url
, function(status
) {
1505 // set the mnemonic phrase
1506 page
.evaluate(function() {
1507 $(".phrase").val("abandon abandon ability").trigger("input");
1509 waitForGenerate(function() {
1510 // select the bip32 tab so custom derivation path can be set
1511 page
.evaluate(function() {
1512 $("#bip32-tab a").click();
1514 waitForGenerate(function() {
1515 // set the incorrect derivation path
1516 page
.evaluate(function() {
1517 $("#bip32 .path").val("n/0").trigger("input");
1519 waitForFeedback(function() {
1520 var feedback
= page
.evaluate(function() {
1521 return $(".feedback").text();
1523 if (feedback
!= "First character must be 'm'") {
1524 console
.log("Derivation path not starting with m should show error");
1525 console
.log("Error: " + error
);
1535 // Derivation path containing invalid characters shows useful error
1537 page
.open(url
, function(status
) {
1538 // set the mnemonic phrase
1539 page
.evaluate(function() {
1540 $(".phrase").val("abandon abandon ability").trigger("input");
1542 waitForGenerate(function() {
1543 // select the bip32 tab so custom derivation path can be set
1544 page
.evaluate(function() {
1545 $("#bip32-tab a").click();
1547 waitForGenerate(function() {
1548 // set the incorrect derivation path
1549 page
.evaluate(function() {
1550 $("#bip32 .path").val("m/1/0wrong1/1").trigger("input");
1552 waitForFeedback(function() {
1553 var feedback
= page
.evaluate(function() {
1554 return $(".feedback").text();
1556 if (feedback
!= "Invalid characters 0wrong1 found at depth 2") {
1557 console
.log("Derivation path with invalid characters should show error");
1558 console
.log("Error: " + error
);
1568 // Github Issue 11: Default word length is 15
1569 // https://github.com/iancoleman/bip39/issues/11
1571 page
.open(url
, function(status
) {
1572 // get the word length
1573 var defaultLength
= page
.evaluate(function() {
1574 return $(".strength").val();
1576 if (defaultLength
!= 15) {
1577 console
.log("Default word length is not 15");
1585 // Github Issue 12: Generate more rows with private keys hidden
1586 // https://github.com/iancoleman/bip39/issues/12
1588 page
.open(url
, function(status
) {
1590 page
.evaluate(function() {
1591 $(".phrase").val("abandon abandon ability");
1592 $(".phrase").trigger("input");
1594 waitForGenerate(function() {
1595 // toggle private keys hidden, then generate more addresses
1596 page
.evaluate(function() {
1597 $(".private-key-toggle").click();
1600 waitForGenerate(function() {
1601 // check more have been generated
1603 var numPrivKeys
= page
.evaluate(function() {
1604 return $(".privkey").length
;
1606 if (numPrivKeys
!= expected
) {
1607 console
.log("Wrong number of addresses when clicking 'more' with hidden privkeys");
1608 console
.log("Expected: " + expected
);
1609 console
.log("Actual: " + numPrivKeys
);
1612 // check no private keys are shown
1613 var numHiddenPrivKeys
= page
.evaluate(function() {
1614 return $(".privkey span[class=invisible]").length
;
1616 if (numHiddenPrivKeys
!= expected
) {
1617 console
.log("Generating more does not retain hidden state of privkeys");
1618 console
.log("Expected: " + expected
);
1619 console
.log("Actual: " + numHiddenPrivKeys
);
1628 // Github Issue 19: Mnemonic is not sensitive to whitespace
1629 // https://github.com/iancoleman/bip39/issues/19
1631 page
.open(url
, function(status
) {
1633 var expected
= "xprv9s21ZrQH143K3isaZsWbKVoTtbvd34Y1ZGRugGdMeBGbM3AgBVzTH159mj1cbbtYSJtQr65w6L5xy5L9SFC7c9VJZWHxgAzpj4mun5LhrbC";
1634 page
.evaluate(function() {
1635 var doubleSpace
= " ";
1636 $(".phrase").val("urge cat" + doubleSpace
+ "bid");
1637 $(".phrase").trigger("input");
1639 waitForGenerate(function() {
1640 // Check the bip32 root key is correct
1641 var actual
= page
.evaluate(function() {
1642 return $(".root-key").val();
1644 if (actual
!= expected
) {
1645 console
.log("Mnemonic is sensitive to whitespace");
1646 console
.log("Expected: " + expected
);
1647 console
.log("Actual: " + actual
);
1655 // Github Issue 23: Part 1: Use correct derivation path when changing tabs
1656 // https://github.com/iancoleman/bip39/issues/23
1658 page
.open(url
, function(status
) {
1659 // 1) and 2) set the phrase
1660 page
.evaluate(function() {
1661 $(".phrase").val("abandon abandon ability").trigger("input");
1663 waitForGenerate(function() {
1664 // 3) select bip32 tab
1665 page
.evaluate(function() {
1666 $("#bip32-tab a").click();
1668 waitForGenerate(function() {
1669 // 4) switch from bitcoin to litecoin
1670 page
.evaluate(function() {
1671 $(".network").val("2").trigger("change");
1673 waitForGenerate(function() {
1674 // 5) Check derivation path is displayed correctly
1675 var expected
= "m/0/0";
1676 var actual
= page
.evaluate(function() {
1677 return $(".index:first").text();
1679 if (actual
!= expected
) {
1680 console
.log("Github Issue 23 Part 1: derivation path display error");
1681 console
.log("Expected: " + expected
);
1682 console
.log("Actual: " + actual
);
1685 // 5) Check address is displayed correctly
1686 var expected
= "LS8MP5LZ5AdzSZveRrjm3aYVoPgnfFh5T5";
1687 var actual
= page
.evaluate(function() {
1688 return $(".address:first").text();
1690 if (actual
!= expected
) {
1691 console
.log("Github Issue 23 Part 1: address display error");
1692 console
.log("Expected: " + expected
);
1693 console
.log("Actual: " + actual
);
1703 // Github Issue 23 Part 2: Coin selection in derivation path
1704 // https://github.com/iancoleman/bip39/issues/23#issuecomment-238011920
1706 page
.open(url
, function(status
) {
1708 page
.evaluate(function() {
1709 $(".phrase").val("abandon abandon ability").trigger("input");
1711 waitForGenerate(function() {
1712 // switch from bitcoin to clam
1713 page
.evaluate(function() {
1714 $(".network").val("9").trigger("change");
1716 waitForGenerate(function() {
1717 // check derivation path is displayed correctly
1718 var expected
= "m/44'/23'/0'/0/0";
1719 var actual
= page
.evaluate(function() {
1720 return $(".index:first").text();
1722 if (actual
!= expected
) {
1723 console
.log("Github Issue 23 Part 2: Coin in BIP44 derivation path is incorrect");
1724 console
.log("Expected: " + expected
);
1725 console
.log("Actual: " + actual
);
1734 // Github Issue 26: When using a Root key derrived altcoins are incorrect
1735 // https://github.com/iancoleman/bip39/issues/26
1737 page
.open(url
, function(status
) {
1738 // 1) 2) and 3) set the root key
1739 page
.evaluate(function() {
1740 $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi").trigger("input");
1742 waitForGenerate(function() {
1743 // 4) switch from bitcoin to viacoin
1744 page
.evaluate(function() {
1745 $(".network").val("6").trigger("change");
1747 waitForGenerate(function() {
1748 // 5) ensure the derived address is correct
1749 var expected
= "Vq9Eq4N5SQnjqZvxtxzo7hZPW5XnyJsmXT";
1750 var actual
= page
.evaluate(function() {
1751 return $(".address:first").text();
1753 if (actual
!= expected
) {
1754 console
.log("Github Issue 26: address is incorrect when changing networks and using root-key to derive");
1755 console
.log("Expected: " + expected
);
1756 console
.log("Actual: " + actual
);
1765 // Selecting a language with no existing phrase should generate a phrase in
1768 page
.open(url
, function(status
) {
1769 // Select a language
1770 // Need to manually simulate hash being set due to quirk between
1771 // 'click' event triggered by javascript vs triggered by mouse.
1772 // Perhaps look into page.sendEvent
1773 // http://phantomjs.org/api/webpage/method/send-event.html
1774 page
.evaluate(function() {
1775 window
.location
.hash
= "#japanese";
1776 $("a[href='#japanese']").trigger("click");
1778 waitForGenerate(function() {
1779 // Check the mnemonic is in Japanese
1780 var phrase
= page
.evaluate(function() {
1781 return $(".phrase").val();
1783 if (phrase
.length
<= 0) {
1784 console
.log("No Japanese phrase generated");
1787 if (phrase
.charCodeAt(0) < 128) {
1788 console
.log("First character of Japanese phrase is ascii");
1789 console
.log("Phrase: " + phrase
);
1797 // Selecting a language with existing phrase should update the phrase to use
1800 page
.open(url
, function(status
) {
1801 // Set the phrase to an English phrase.
1802 page
.evaluate(function() {
1803 $(".phrase").val("abandon abandon ability").trigger("input");
1805 waitForGenerate(function() {
1806 // Change to Italian
1807 // Need to manually simulate hash being set due to quirk between
1808 // 'click' event triggered by javascript vs triggered by mouse.
1809 // Perhaps look into page.sendEvent
1810 // http://phantomjs.org/api/webpage/method/send-event.html
1811 page
.evaluate(function() {
1812 window
.location
.hash
= "#italian";
1813 $("a[href='#italian']").trigger("click");
1815 waitForGenerate(function() {
1816 // Check only the language changes, not the phrase
1817 var expected
= "abaco abaco abbaglio";
1818 var actual
= page
.evaluate(function() {
1819 return $(".phrase").val();
1821 if (actual
!= expected
) {
1822 console
.log("Changing language with existing phrase");
1823 console
.log("Expected: " + expected
);
1824 console
.log("Actual: " + actual
);
1827 // Check the address is correct
1828 var expected
= "1Dz5TgDhdki9spa6xbPFbBqv5sjMrx3xgV";
1829 var actual
= page
.evaluate(function() {
1830 return $(".address:first").text();
1832 if (actual
!= expected
) {
1833 console
.log("Changing language generates incorrect address");
1834 console
.log("Expected: " + expected
);
1835 console
.log("Actual: " + actual
);
1844 // Suggested replacement for erroneous word in non-English language
1846 page
.open(url
, function(status
) {
1847 // Set an incorrect phrase in Italian
1848 page
.evaluate(function() {
1849 $(".phrase").val("abaco abaco zbbaglio").trigger("input");
1851 waitForFeedback(function() {
1852 // Check the suggestion is correct
1853 var feedback
= page
.evaluate(function() {
1854 return $(".feedback").text();
1856 if (feedback
.indexOf("did you mean abbaglio?") < 0) {
1857 console
.log("Incorrect Italian word does not show suggested replacement");
1858 console
.log("Error: " + error
);
1867 // Japanese word does not break across lines.
1869 // https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md#japanese
1871 page
.open(url
, function(status
) {
1872 hasWordBreakCss
= page
.content
.indexOf("word-break: keep-all;") > -1;
1873 if (!hasWordBreakCss
) {
1874 console
.log("Japanese words can break across lines mid-word");
1875 console
.log("Check CSS for '.phrase { word-break: keep-all; }'");
1878 // Run the next test
1883 // Language can be specified at page load using hash value in url
1885 page
.open(url
, function(status
) {
1886 // Set the page hash as if it were on a fresh page load
1887 page
.evaluate(function() {
1888 window
.location
.hash
= "#japanese";
1890 // Generate a random phrase
1891 page
.evaluate(function() {
1892 $(".generate").trigger("click");
1894 waitForGenerate(function() {
1895 // Check the phrase is in Japanese
1896 var phrase
= page
.evaluate(function() {
1897 return $(".phrase").val();
1899 if (phrase
.length
<= 0) {
1900 console
.log("No phrase generated using url hash");
1903 if (phrase
.charCodeAt(0) < 128) {
1904 console
.log("Language not detected from url hash on page load.");
1905 console
.log("Phrase: " + phrase
);
1913 // If you wish to add more tests, do so here...
1915 // Here is a blank test template
1919 page.open(url, function(status) {
1920 // Do something on the page
1921 page.evaluate(function() {
1922 $(".phrase").val("abandon abandon ability").trigger("input");
1924 waitForGenerate(function() {
1925 // Check the result of doing the thing
1926 var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
1927 var actual = page.evaluate(function() {
1928 return $(".address:first").text();
1930 if (actual != expected) {
1931 console.log("A specific message about what failed");
1932 console.log("Expected: " + expected);
1933 console.log("Actual: " + actual);
1936 // Run the next test
1946 console
.log("Running tests...");
1947 tests
= shuffle(tests
);