1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
// Usage:
// $ phantomjs tests.js
var page = require('webpage').create();
var url = 'src/index.html';
page.onResourceError = function(e) {
console.log("Error loading " + e.url);
phantom.exit();
}
function fail() {
console.log("Failed");
phantom.exit();
}
function next() {
if (tests.length > 0) {
var testsStr = tests.length == 1 ? "test" : "tests";
console.log(tests.length + " " + testsStr + " remaining");
tests.shift()();
}
else {
console.log("Finished with 0 failures");
phantom.exit();
}
}
tests = [
// Page loads with status of 'success'
function() {
page.open(url, function(status) {
if (status != "success") {
console.log("Page did not load with status 'success'");
fail();
}
next();
});
},
// Page has text
function() {
page.open(url, function(status) {
var content = page.evaluate(function() {
return document.body.textContent.trim();
});
if (!content) {
console.log("Page does not have text");
fail();
}
next();
});
},
// Entering mnemonic generates addresses
function() {
page.open(url, function(status) {
var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
// set the phrase
page.evaluate(function() {
$(".phrase").val("abandon abandon ability").trigger("input");
});
// get the address
setTimeout(function() {
var actual = page.evaluate(function() {
return $(".address:first").text();
});
if (actual != expected) {
console.log("Mnemonic did not generate address");
console.log("Expected: " + expected);
console.log("Got: " + actual);
fail();
}
next();
}, 1000);
});
},
// Random button generates random mnemonic
function() {
page.open(url, function(status) {
// check initial phrase is empty
var phrase = page.evaluate(function() {
return $(".phrase").text();
});
if (phrase != "") {
console.log("Initial phrase is not blank");
fail();
}
// press the 'generate' button
page.evaluate(function() {
$(".generate").click();
});
// get the new phrase
setTimeout(function() {
var phrase = page.evaluate(function() {
return $(".phrase").val();
});
if (phrase.length <= 0) {
console.log("Phrase not generated by pressing button");
fail();
}
next();
}, 1000);
});
},
// Mnemonic length can be customized
function() {
page.open(url, function(status) {
// set the length to 6
var expectedLength = 6;
page.evaluate(function() {
$(".strength").val(expectedLength);
});
// press the 'generate' button
page.evaluate(function() {
$(".generate").click();
});
// check the new phrase is six words long
setTimeout(function() {
var actualLength = page.evaluate(function() {
var words = $(".phrase").val().split(" ");
return words.length;
});
if (actualLength != expectedLength) {
console.log("Phrase not generated with correct length");
console.log("Expected: " + expectedLength);
console.log("Actual: " + actualLength);
fail();
}
}, 200);
next();
});
},
// TODO finish these tests
// Passphrase can be set
// Network can be set to bitcoin testnet
// Network can be set to litecoin
// Network can be set to dogecoin
// Network can be set to shadowcash
// Network can be set to shadowcash testnet
// Network can be set to viacoin
// Network can be set to viacoin testnet
// Network can be set to jumbucks
// Network can be set to clam
// BIP39 seed is set from phrase
// BIP32 root key is set from phrase
// Tabs show correct addresses when changed
// BIP44 derivation path is shown
// BIP44 extended private key is shown
// BIP44 extended public key is shown
// BIP44 purpose field changes address list
// BIP44 coin field changes address list
// BIP44 account field changes address list
// BIP44 external/internal field changes address list
// BIP32 derivation path can be set
// BIP32 can use hardened derivation paths
// BIP32 extended private key is shown
// BIP32 extended public key is shown
// Derivation path is shown in table
// Derivation path for address can be hardened
// Derivation path visibility can be toggled
// Address is shown
// Addresses are shown in order of derivation path
// Address visibility can be toggled
// Private key is shown
// Private key visibility can be toggled
// More addresses can be generated
// A custom number of additional addresses can be generated
// Additional addresses are shown in order of derivation path
// BIP32 root key can be set by the user
// Setting BIP32 clears the existing phrase, passphrase and seed
// Custom BIP32 root key is used when changing the derivation path
// Incorrect mnemonic shows error
// Incorrect word shows suggested replacement
// Incorrect BIP32 root key shows error
// Derivation path not starting with m shows error
// Derivation path containing invalid characters shows useful error
// Github Issue 11: Default word length is 15
// https://github.com/dcpos/bip39/issues/11
// Github Issue 12: Generate more rows with private keys hidden
// https://github.com/dcpos/bip39/issues/12
// Github Issue 19: Mnemonic is not sensitive to whitespace
// https://github.com/dcpos/bip39/issues/19
// Github Issue 23: Use correct derivation path when changing tabs
// https://github.com/dcpos/bip39/issues/23
];
console.log("Running tests...");
next();
|