]>
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';
8 page
.onResourceError = function(e
) {
9 console
.log("Error loading " + e
.url
);
14 console
.log("Failed");
19 if (tests
.length
> 0) {
20 var testsStr
= tests
.length
== 1 ? "test" : "tests";
21 console
.log(tests
.length
+ " " + testsStr
+ " remaining");
25 console
.log("Finished with 0 failures");
32 // Page loads with status of 'success'
34 page
.open(url
, function(status
) {
35 if (status
!= "success") {
36 console
.log("Page did not load with status 'success'");
45 page
.open(url
, function(status
) {
46 var content
= page
.evaluate(function() {
47 return document
.body
.textContent
.trim();
50 console
.log("Page does not have text");
57 // Entering mnemonic generates addresses
59 page
.open(url
, function(status
) {
60 var expected
= "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
62 page
.evaluate(function() {
63 $(".phrase").val("abandon abandon ability").trigger("input");
66 setTimeout(function() {
67 var actual
= page
.evaluate(function() {
68 return $(".address:first").text();
70 if (actual
!= expected
) {
71 console
.log("Mnemonic did not generate address");
72 console
.log("Expected: " + expected
);
73 console
.log("Got: " + actual
);
81 // Random button generates random mnemonic
83 page
.open(url
, function(status
) {
84 // check initial phrase is empty
85 var phrase
= page
.evaluate(function() {
86 return $(".phrase").text();
89 console
.log("Initial phrase is not blank");
92 // press the 'generate' button
93 page
.evaluate(function() {
94 $(".generate").click();
97 setTimeout(function() {
98 var phrase
= page
.evaluate(function() {
99 return $(".phrase").val();
101 if (phrase
.length
<= 0) {
102 console
.log("Phrase not generated by pressing button");
110 // Mnemonic length can be customized
112 page
.open(url
, function(status
) {
113 // set the length to 6
114 var expectedLength
= "6";
115 page
.evaluate(function() {
116 $(".strength option[selected]").removeAttr("selected");
117 $(".strength option[value=6]").prop("selected", true);
119 // press the 'generate' button
120 page
.evaluate(function() {
121 $(".generate").click();
123 // check the new phrase is six words long
124 setTimeout(function() {
125 var actualLength
= page
.evaluate(function() {
126 var words
= $(".phrase").val().split(" ");
129 if (actualLength
!= expectedLength
) {
130 console
.log("Phrase not generated with correct length");
131 console
.log("Expected: " + expectedLength
);
132 console
.log("Actual: " + actualLength
);
140 // Passphrase can be set
142 page
.open(url
, function(status
) {
143 // set the phrase and passphrase
144 var expected
= "15pJzUWPGzR7avffV9nY5by4PSgSKG9rba";
145 page
.evaluate(function() {
146 $(".phrase").val("abandon abandon ability");
147 $(".passphrase").val("secure_passphrase").trigger("input");
149 // check the address is generated correctly
150 setTimeout(function() {
151 var actual
= page
.evaluate(function() {
152 return $(".address:first").text();
154 if (actual
!= expected
) {
155 console
.log("Passphrase results in wrong address");
156 console
.log("Expected: " + expected
);
157 console
.log("Actual: " + actual
);
165 // Network can be set to bitcoin testnet
167 page
.open(url
, function(status
) {
168 // set the phrase and coin
169 var expected
= "mucaU5iiDaJDb69BHLeDv8JFfGiyg2nJKi";
170 page
.evaluate(function() {
171 $(".phrase").val("abandon abandon ability");
172 $(".phrase").trigger("input");
173 $(".network option[selected]").removeAttr("selected");
174 $(".network option[value=1]").prop("selected", true);
175 $(".network").trigger("change");
177 // check the address is generated correctly
178 setTimeout(function() {
179 var actual
= page
.evaluate(function() {
180 return $(".address:first").text();
182 if (actual
!= expected
) {
183 console
.log("Bitcoin testnet address is incorrect");
184 console
.log("Expected: " + expected
);
185 console
.log("Actual: " + actual
);
193 // Network can be set to litecoin
195 page
.open(url
, function(status
) {
196 // set the phrase and coin
197 var expected
= "LQ4XU8RX2ULPmPq9FcUHdVmPVchP9nwXdn";
198 page
.evaluate(function() {
199 $(".phrase").val("abandon abandon ability");
200 $(".phrase").trigger("input");
201 $(".network option[selected]").removeAttr("selected");
202 $(".network option[value=2]").prop("selected", true);
203 $(".network").trigger("change");
205 // check the address is generated correctly
206 setTimeout(function() {
207 var actual
= page
.evaluate(function() {
208 return $(".address:first").text();
210 if (actual
!= expected
) {
211 console
.log("Litecoin address is incorrect");
212 console
.log("Expected: " + expected
);
213 console
.log("Actual: " + actual
);
221 // Network can be set to dogecoin
223 page
.open(url
, function(status
) {
224 // set the phrase and coin
225 var expected
= "DPQH2AtuzkVSG6ovjKk4jbUmZ6iXLpgbJA";
226 page
.evaluate(function() {
227 $(".phrase").val("abandon abandon ability");
228 $(".phrase").trigger("input");
229 $(".network option[selected]").removeAttr("selected");
230 $(".network option[value=3]").prop("selected", true);
231 $(".network").trigger("change");
233 // check the address is generated correctly
234 setTimeout(function() {
235 var actual
= page
.evaluate(function() {
236 return $(".address:first").text();
238 if (actual
!= expected
) {
239 console
.log("Dogecoin address is incorrect");
240 console
.log("Expected: " + expected
);
241 console
.log("Actual: " + actual
);
249 // Network can be set to shadowcash
251 page
.open(url
, function(status
) {
252 // set the phrase and coin
253 var expected
= "SiSZtfYAXEFvMm3XM8hmtkGDyViRwErtCG";
254 page
.evaluate(function() {
255 $(".phrase").val("abandon abandon ability");
256 $(".phrase").trigger("input");
257 $(".network option[selected]").removeAttr("selected");
258 $(".network option[value=4]").prop("selected", true);
259 $(".network").trigger("change");
261 // check the address is generated correctly
262 setTimeout(function() {
263 var actual
= page
.evaluate(function() {
264 return $(".address:first").text();
266 if (actual
!= expected
) {
267 console
.log("Shadowcash address is incorrect");
268 console
.log("Expected: " + expected
);
269 console
.log("Actual: " + actual
);
277 // Network can be set to shadowcash testnet
279 page
.open(url
, function(status
) {
280 // set the phrase and coin
281 var expected
= "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
282 page
.evaluate(function() {
283 $(".phrase").val("abandon abandon ability");
284 $(".phrase").trigger("input");
285 $(".network option[selected]").removeAttr("selected");
286 $(".network option[value=5]").prop("selected", true);
287 $(".network").trigger("change");
289 // check the address is generated correctly
290 setTimeout(function() {
291 var actual
= page
.evaluate(function() {
292 return $(".address:first").text();
294 if (actual
!= expected
) {
295 console
.log("Shadowcash testnet address is incorrect");
296 console
.log("Expected: " + expected
);
297 console
.log("Actual: " + actual
);
305 // Network can be set to viacoin
307 page
.open(url
, function(status
) {
308 // set the phrase and coin
309 var expected
= "Vq9Eq4N5SQnjqZvxtxzo7hZPW5XnyJsmXT";
310 page
.evaluate(function() {
311 $(".phrase").val("abandon abandon ability");
312 $(".phrase").trigger("input");
313 $(".network option[selected]").removeAttr("selected");
314 $(".network option[value=6]").prop("selected", true);
315 $(".network").trigger("change");
317 // check the address is generated correctly
318 setTimeout(function() {
319 var actual
= page
.evaluate(function() {
320 return $(".address:first").text();
322 if (actual
!= expected
) {
323 console
.log("Viacoin address is incorrect");
324 console
.log("Expected: " + expected
);
325 console
.log("Actual: " + actual
);
333 // Network can be set to viacoin testnet
335 page
.open(url
, function(status
) {
336 // set the phrase and coin
337 var expected
= "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
338 page
.evaluate(function() {
339 $(".phrase").val("abandon abandon ability");
340 $(".phrase").trigger("input");
341 $(".network option[selected]").removeAttr("selected");
342 $(".network option[value=7]").prop("selected", true);
343 $(".network").trigger("change");
345 // check the address is generated correctly
346 setTimeout(function() {
347 var actual
= page
.evaluate(function() {
348 return $(".address:first").text();
350 if (actual
!= expected
) {
351 console
.log("Viacoin testnet address is incorrect");
352 console
.log("Expected: " + expected
);
353 console
.log("Actual: " + actual
);
361 // Network can be set to jumbucks
363 page
.open(url
, function(status
) {
364 // set the phrase and coin
365 var expected
= "JLEXccwDXADK4RxBPkRez7mqsHVoJBEUew";
366 page
.evaluate(function() {
367 $(".phrase").val("abandon abandon ability");
368 $(".phrase").trigger("input");
369 $(".network option[selected]").removeAttr("selected");
370 $(".network option[value=8]").prop("selected", true);
371 $(".network").trigger("change");
373 // check the address is generated correctly
374 setTimeout(function() {
375 var actual
= page
.evaluate(function() {
376 return $(".address:first").text();
378 if (actual
!= expected
) {
379 console
.log("Jumbucks address is incorrect");
380 console
.log("Expected: " + expected
);
381 console
.log("Actual: " + actual
);
389 // Network can be set to clam
391 page
.open(url
, function(status
) {
392 // set the phrase and coin
393 var expected
= "xCp4sakjVx4pUAZ6cBCtuin8Ddb6U1sk9y";
394 page
.evaluate(function() {
395 $(".phrase").val("abandon abandon ability");
396 $(".phrase").trigger("input");
397 $(".network option[selected]").removeAttr("selected");
398 $(".network option[value=9]").prop("selected", true);
399 $(".network").trigger("change");
401 // check the address is generated correctly
402 setTimeout(function() {
403 var actual
= page
.evaluate(function() {
404 return $(".address:first").text();
406 if (actual
!= expected
) {
407 console
.log("CLAM address is incorrect");
408 console
.log("Expected: " + expected
);
409 console
.log("Actual: " + actual
);
417 // BIP39 seed is set from phrase
419 page
.open(url
, function(status
) {
421 var expected
= "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
422 page
.evaluate(function() {
423 $(".phrase").val("abandon abandon ability");
424 $(".phrase").trigger("input");
426 // check the address is generated correctly
427 setTimeout(function() {
428 var actual
= page
.evaluate(function() {
429 return $(".seed").val();
431 if (actual
!= expected
) {
432 console
.log("BIP39 seed is incorrectly generated from mnemonic");
433 console
.log("Expected: " + expected
);
434 console
.log("Actual: " + actual
);
442 // BIP32 root key is set from phrase
444 page
.open(url
, function(status
) {
446 var expected
= "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
447 page
.evaluate(function() {
448 $(".phrase").val("abandon abandon ability");
449 $(".phrase").trigger("input");
451 // check the address is generated correctly
452 setTimeout(function() {
453 var actual
= page
.evaluate(function() {
454 return $(".root-key").val();
456 if (actual
!= expected
) {
457 console
.log("Root key is incorrectly generated from mnemonic");
458 console
.log("Expected: " + expected
);
459 console
.log("Actual: " + actual
);
467 // TODO finish these tests
469 // Tabs show correct addresses when changed
471 // BIP44 derivation path is shown
472 // BIP44 extended private key is shown
473 // BIP44 extended public key is shown
474 // BIP44 purpose field changes address list
475 // BIP44 coin field changes address list
476 // BIP44 account field changes address list
477 // BIP44 external/internal field changes address list
479 // BIP32 derivation path can be set
480 // BIP32 can use hardened derivation paths
481 // BIP32 extended private key is shown
482 // BIP32 extended public key is shown
484 // Derivation path is shown in table
485 // Derivation path for address can be hardened
486 // Derivation path visibility can be toggled
488 // Addresses are shown in order of derivation path
489 // Address visibility can be toggled
490 // Private key is shown
491 // Private key visibility can be toggled
493 // More addresses can be generated
494 // A custom number of additional addresses can be generated
495 // Additional addresses are shown in order of derivation path
497 // BIP32 root key can be set by the user
498 // Setting BIP32 root key clears the existing phrase, passphrase and seed
499 // Clearing of phrase, passphrase and seed can be cancelled by user
500 // Custom BIP32 root key is used when changing the derivation path
502 // Incorrect mnemonic shows error
503 // Incorrect word shows suggested replacement
504 // Incorrect BIP32 root key shows error
505 // Derivation path not starting with m shows error
506 // Derivation path containing invalid characters shows useful error
508 // Github Issue 11: Default word length is 15
509 // https://github.com/dcpos/bip39/issues/11
511 // Github Issue 12: Generate more rows with private keys hidden
512 // https://github.com/dcpos/bip39/issues/12
514 // Github Issue 19: Mnemonic is not sensitive to whitespace
515 // https://github.com/dcpos/bip39/issues/19
517 // Github Issue 23: Use correct derivation path when changing tabs
518 // https://github.com/dcpos/bip39/issues/23
522 console
.log("Running tests...");