]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blame - tests.js
Test bip32 root key as generated from mnemonic
[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';
7
8page.onResourceError = function(e) {
9 console.log("Error loading " + e.url);
10 phantom.exit();
11}
12
13function fail() {
14 console.log("Failed");
15 phantom.exit();
16}
17
18function next() {
19 if (tests.length > 0) {
20 var testsStr = tests.length == 1 ? "test" : "tests";
21 console.log(tests.length + " " + testsStr + " remaining");
22 tests.shift()();
23 }
24 else {
25 console.log("Finished with 0 failures");
26 phantom.exit();
27 }
28}
29
30tests = [
31
32// Page loads with status of 'success'
33function() {
34page.open(url, function(status) {
35 if (status != "success") {
36 console.log("Page did not load with status 'success'");
37 fail();
38 }
39 next();
40});
41},
42
43// Page has text
44function() {
45page.open(url, function(status) {
46 var content = page.evaluate(function() {
47 return document.body.textContent.trim();
48 });
49 if (!content) {
50 console.log("Page does not have text");
51 fail();
52 }
53 next();
54});
55},
56
57// Entering mnemonic generates addresses
58function() {
59page.open(url, function(status) {
60 var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
61 // set the phrase
62 page.evaluate(function() {
63 $(".phrase").val("abandon abandon ability").trigger("input");
64 });
65 // get the address
66 setTimeout(function() {
67 var actual = page.evaluate(function() {
68 return $(".address:first").text();
69 });
70 if (actual != expected) {
71 console.log("Mnemonic did not generate address");
72 console.log("Expected: " + expected);
73 console.log("Got: " + actual);
74 fail();
75 }
76 next();
77 }, 1000);
78});
79},
80
81// Random button generates random mnemonic
82function() {
83page.open(url, function(status) {
84 // check initial phrase is empty
85 var phrase = page.evaluate(function() {
86 return $(".phrase").text();
87 });
88 if (phrase != "") {
89 console.log("Initial phrase is not blank");
90 fail();
91 }
92 // press the 'generate' button
93 page.evaluate(function() {
94 $(".generate").click();
95 });
96 // get the new phrase
97 setTimeout(function() {
98 var phrase = page.evaluate(function() {
99 return $(".phrase").val();
100 });
101 if (phrase.length <= 0) {
102 console.log("Phrase not generated by pressing button");
103 fail();
104 }
105 next();
106 }, 1000);
107});
108},
109
110// Mnemonic length can be customized
111function() {
112page.open(url, function(status) {
113 // set the length to 6
54563907 114 var expectedLength = "6";
88e2cdaa 115 page.evaluate(function() {
54563907
IC
116 $(".strength option[selected]").removeAttr("selected");
117 $(".strength option[value=6]").prop("selected", true);
88e2cdaa
IC
118 });
119 // press the 'generate' button
120 page.evaluate(function() {
121 $(".generate").click();
122 });
123 // check the new phrase is six words long
124 setTimeout(function() {
125 var actualLength = page.evaluate(function() {
126 var words = $(".phrase").val().split(" ");
127 return words.length;
128 });
129 if (actualLength != expectedLength) {
130 console.log("Phrase not generated with correct length");
131 console.log("Expected: " + expectedLength);
132 console.log("Actual: " + actualLength);
133 fail();
134 }
54563907
IC
135 next();
136 }, 1000);
88e2cdaa
IC
137});
138},
139
88e2cdaa 140// Passphrase can be set
54563907
IC
141function() {
142page.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");
148 });
149 // check the address is generated correctly
150 setTimeout(function() {
151 var actual = page.evaluate(function() {
152 return $(".address:first").text();
153 });
154 if (actual != expected) {
155 console.log("Passphrase results in wrong address");
156 console.log("Expected: " + expected);
157 console.log("Actual: " + actual);
158 fail();
159 }
160 next();
161 }, 1000);
162});
163},
164
88e2cdaa 165// Network can be set to bitcoin testnet
54563907
IC
166function() {
167page.open(url, function(status) {
59193779 168 // set the phrase and coin
54563907
IC
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");
176 });
177 // check the address is generated correctly
178 setTimeout(function() {
179 var actual = page.evaluate(function() {
180 return $(".address:first").text();
181 });
182 if (actual != expected) {
183 console.log("Bitcoin testnet address is incorrect");
184 console.log("Expected: " + expected);
185 console.log("Actual: " + actual);
186 fail();
187 }
188 next();
189 }, 1000);
190});
191},
192
88e2cdaa 193// Network can be set to litecoin
59193779
IC
194function() {
195page.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");
204 });
205 // check the address is generated correctly
206 setTimeout(function() {
207 var actual = page.evaluate(function() {
208 return $(".address:first").text();
209 });
210 if (actual != expected) {
211 console.log("Litecoin address is incorrect");
212 console.log("Expected: " + expected);
213 console.log("Actual: " + actual);
214 fail();
215 }
216 next();
217 }, 1000);
218});
219},
220
88e2cdaa 221// Network can be set to dogecoin
59193779
IC
222function() {
223page.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");
232 });
233 // check the address is generated correctly
234 setTimeout(function() {
235 var actual = page.evaluate(function() {
236 return $(".address:first").text();
237 });
238 if (actual != expected) {
239 console.log("Dogecoin address is incorrect");
240 console.log("Expected: " + expected);
241 console.log("Actual: " + actual);
242 fail();
243 }
244 next();
245 }, 1000);
246});
247},
248
88e2cdaa 249// Network can be set to shadowcash
59193779
IC
250function() {
251page.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");
260 });
261 // check the address is generated correctly
262 setTimeout(function() {
263 var actual = page.evaluate(function() {
264 return $(".address:first").text();
265 });
266 if (actual != expected) {
267 console.log("Shadowcash address is incorrect");
268 console.log("Expected: " + expected);
269 console.log("Actual: " + actual);
270 fail();
271 }
272 next();
273 }, 1000);
274});
275},
276
88e2cdaa 277// Network can be set to shadowcash testnet
59193779
IC
278function() {
279page.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");
288 });
289 // check the address is generated correctly
290 setTimeout(function() {
291 var actual = page.evaluate(function() {
292 return $(".address:first").text();
293 });
294 if (actual != expected) {
295 console.log("Shadowcash testnet address is incorrect");
296 console.log("Expected: " + expected);
297 console.log("Actual: " + actual);
298 fail();
299 }
300 next();
301 }, 1000);
302});
303},
304
88e2cdaa 305// Network can be set to viacoin
59193779
IC
306function() {
307page.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");
316 });
317 // check the address is generated correctly
318 setTimeout(function() {
319 var actual = page.evaluate(function() {
320 return $(".address:first").text();
321 });
322 if (actual != expected) {
323 console.log("Viacoin address is incorrect");
324 console.log("Expected: " + expected);
325 console.log("Actual: " + actual);
326 fail();
327 }
328 next();
329 }, 1000);
330});
331},
332
88e2cdaa 333// Network can be set to viacoin testnet
59193779
IC
334function() {
335page.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");
344 });
345 // check the address is generated correctly
346 setTimeout(function() {
347 var actual = page.evaluate(function() {
348 return $(".address:first").text();
349 });
350 if (actual != expected) {
351 console.log("Viacoin testnet address is incorrect");
352 console.log("Expected: " + expected);
353 console.log("Actual: " + actual);
354 fail();
355 }
356 next();
357 }, 1000);
358});
359},
360
88e2cdaa 361// Network can be set to jumbucks
59193779
IC
362function() {
363page.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");
372 });
373 // check the address is generated correctly
374 setTimeout(function() {
375 var actual = page.evaluate(function() {
376 return $(".address:first").text();
377 });
378 if (actual != expected) {
379 console.log("Jumbucks address is incorrect");
380 console.log("Expected: " + expected);
381 console.log("Actual: " + actual);
382 fail();
383 }
384 next();
385 }, 1000);
386});
387},
388
88e2cdaa 389// Network can be set to clam
59193779
IC
390function() {
391page.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");
400 });
401 // check the address is generated correctly
402 setTimeout(function() {
403 var actual = page.evaluate(function() {
404 return $(".address:first").text();
405 });
406 if (actual != expected) {
407 console.log("CLAM address is incorrect");
408 console.log("Expected: " + expected);
409 console.log("Actual: " + actual);
410 fail();
411 }
412 next();
413 }, 1000);
414});
415},
416
88e2cdaa 417// BIP39 seed is set from phrase
c196ad55
IC
418function() {
419page.open(url, function(status) {
420 // set the phrase
421 var expected = "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
422 page.evaluate(function() {
423 $(".phrase").val("abandon abandon ability");
424 $(".phrase").trigger("input");
425 });
426 // check the address is generated correctly
427 setTimeout(function() {
428 var actual = page.evaluate(function() {
429 return $(".seed").val();
430 });
431 if (actual != expected) {
432 console.log("BIP39 seed is incorrectly generated from mnemonic");
433 console.log("Expected: " + expected);
434 console.log("Actual: " + actual);
435 fail();
436 }
437 next();
438 }, 1000);
439});
440},
441
88e2cdaa 442// BIP32 root key is set from phrase
ec60b662
IC
443function() {
444page.open(url, function(status) {
445 // set the phrase
446 var expected = "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
447 page.evaluate(function() {
448 $(".phrase").val("abandon abandon ability");
449 $(".phrase").trigger("input");
450 });
451 // check the address is generated correctly
452 setTimeout(function() {
453 var actual = page.evaluate(function() {
454 return $(".root-key").val();
455 });
456 if (actual != expected) {
457 console.log("Root key is incorrectly generated from mnemonic");
458 console.log("Expected: " + expected);
459 console.log("Actual: " + actual);
460 fail();
461 }
462 next();
463 }, 1000);
464});
465},
466
467// TODO finish these tests
88e2cdaa
IC
468
469// Tabs show correct addresses when changed
470
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
478
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
483
484// Derivation path is shown in table
485// Derivation path for address can be hardened
486// Derivation path visibility can be toggled
487// Address is shown
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
492
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
496
497// BIP32 root key can be set by the user
54563907
IC
498// Setting BIP32 root key clears the existing phrase, passphrase and seed
499// Clearing of phrase, passphrase and seed can be cancelled by user
88e2cdaa
IC
500// Custom BIP32 root key is used when changing the derivation path
501
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
507
508// Github Issue 11: Default word length is 15
509// https://github.com/dcpos/bip39/issues/11
510
511// Github Issue 12: Generate more rows with private keys hidden
512// https://github.com/dcpos/bip39/issues/12
513
514// Github Issue 19: Mnemonic is not sensitive to whitespace
515// https://github.com/dcpos/bip39/issues/19
516
517// Github Issue 23: Use correct derivation path when changing tabs
518// https://github.com/dcpos/bip39/issues/23
519
520];
521
522console.log("Running tests...");
523next();