X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=tests.js;h=8de6391fd7bb0aafe6b9317d9c2b46285998bb2c;hb=adc8ce127d4f8ea0d7e5ede6a82c2791d60ff4d2;hp=287c480ecae45054aa704207160e9042f8a73e79;hpb=ca976aa99b0d4e08b83c36824046d875227dd9a3;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FBIP39.git diff --git a/tests.js b/tests.js index 287c480..8de6391 100644 --- a/tests.js +++ b/tests.js @@ -75,6 +75,40 @@ function waitForFeedback(fn, maxTime) { wait(); } +function waitForEntropyFeedback(fn, maxTime) { + if (!maxTime) { + maxTime = testMaxTime; + } + var origFeedback = page.evaluate(function() { + return $(".entropy-error").text(); + }); + var start = new Date().getTime(); + var wait = function keepWaiting() { + var now = new Date().getTime(); + var hasTimedOut = now - start > maxTime; + if (hasTimedOut) { + console.log("Test timed out"); + fn(); + return; + } + var feedback = page.evaluate(function() { + var feedback = $(".entropy-error"); + if (feedback.css("display") == "none") { + return ""; + } + return feedback.text(); + }); + var hasFinished = feedback != origFeedback; + if (hasFinished) { + fn(); + } + else { + setTimeout(keepWaiting, 100); + } + } + wait(); +} + function next() { if (tests.length > 0) { var testsStr = tests.length == 1 ? "test" : "tests"; @@ -1166,6 +1200,56 @@ page.open(url, function(status) { }); }, +// Public key is shown +function() { +page.open(url, function(status) { + var expected = "033f5aed5f6cfbafaf223188095b5980814897295f723815fea5d3f4b648d0d0b3"; + // set the phrase + page.evaluate(function() { + $(".phrase").val("abandon abandon ability").trigger("input"); + }); + // get the address + waitForGenerate(function() { + var actual = page.evaluate(function() { + return $(".pubkey:first").text(); + }); + if (actual != expected) { + console.log("Public key is not shown"); + console.log("Expected: " + expected); + console.log("Got: " + actual); + fail(); + } + next(); + }); +}); +}, + +// Public key visibility can be toggled +function() { +page.open(url, function(status) { + // set the phrase + page.evaluate(function() { + $(".phrase").val("abandon abandon ability"); + $(".phrase").trigger("input"); + }); + waitForGenerate(function() { + // toggle public key visibility + page.evaluate(function() { + $(".public-key-toggle").click(); + }); + // check the public key is not visible + var isInvisible = page.evaluate(function() { + return $(".pubkey:first span").hasClass("invisible"); + }); + if (!isInvisible) { + console.log("Toggled public key is visible"); + fail(); + } + next(); + }); +}); +}, + // Private key is shown function() { page.open(url, function(status) { @@ -1566,7 +1650,7 @@ page.open(url, function(status) { }, // Github Issue 11: Default word length is 15 -// https://github.com/dcpos/bip39/issues/11 +// https://github.com/iancoleman/bip39/issues/11 function() { page.open(url, function(status) { // get the word length @@ -1583,16 +1667,1141 @@ page.open(url, function(status) { // Github Issue 12: Generate more rows with private keys hidden -// https://github.com/dcpos/bip39/issues/12 +// https://github.com/iancoleman/bip39/issues/12 +function() { +page.open(url, function(status) { + // set the phrase + page.evaluate(function() { + $(".phrase").val("abandon abandon ability"); + $(".phrase").trigger("input"); + }); + waitForGenerate(function() { + // toggle private keys hidden, then generate more addresses + page.evaluate(function() { + $(".private-key-toggle").click(); + $(".more").click(); + }); + waitForGenerate(function() { + // check more have been generated + var expected = 40; + var numPrivKeys = page.evaluate(function() { + return $(".privkey").length; + }); + if (numPrivKeys != expected) { + console.log("Wrong number of addresses when clicking 'more' with hidden privkeys"); + console.log("Expected: " + expected); + console.log("Actual: " + numPrivKeys); + fail(); + } + // check no private keys are shown + var numHiddenPrivKeys = page.evaluate(function() { + return $(".privkey span[class=invisible]").length; + }); + if (numHiddenPrivKeys != expected) { + console.log("Generating more does not retain hidden state of privkeys"); + console.log("Expected: " + expected); + console.log("Actual: " + numHiddenPrivKeys); + fail(); + } + next(); + }); + }); +}); +}, // Github Issue 19: Mnemonic is not sensitive to whitespace -// https://github.com/dcpos/bip39/issues/19 +// https://github.com/iancoleman/bip39/issues/19 +function() { +page.open(url, function(status) { + // set the phrase + var expected = "xprv9s21ZrQH143K3isaZsWbKVoTtbvd34Y1ZGRugGdMeBGbM3AgBVzTH159mj1cbbtYSJtQr65w6L5xy5L9SFC7c9VJZWHxgAzpj4mun5LhrbC"; + page.evaluate(function() { + var doubleSpace = " "; + $(".phrase").val("urge cat" + doubleSpace + "bid"); + $(".phrase").trigger("input"); + }); + waitForGenerate(function() { + // Check the bip32 root key is correct + var actual = page.evaluate(function() { + return $(".root-key").val(); + }); + if (actual != expected) { + console.log("Mnemonic is sensitive to whitespace"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + next(); + }); +}); +}, + +// Github Issue 23: Part 1: Use correct derivation path when changing tabs +// https://github.com/iancoleman/bip39/issues/23 +function() { +page.open(url, function(status) { + // 1) and 2) set the phrase + page.evaluate(function() { + $(".phrase").val("abandon abandon ability").trigger("input"); + }); + waitForGenerate(function() { + // 3) select bip32 tab + page.evaluate(function() { + $("#bip32-tab a").click(); + }); + waitForGenerate(function() { + // 4) switch from bitcoin to litecoin + page.evaluate(function() { + $(".network").val("2").trigger("change"); + }); + waitForGenerate(function() { + // 5) Check derivation path is displayed correctly + var expected = "m/0/0"; + var actual = page.evaluate(function() { + return $(".index:first").text(); + }); + if (actual != expected) { + console.log("Github Issue 23 Part 1: derivation path display error"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + // 5) Check address is displayed correctly + var expected = "LS8MP5LZ5AdzSZveRrjm3aYVoPgnfFh5T5"; + var actual = page.evaluate(function() { + return $(".address:first").text(); + }); + if (actual != expected) { + console.log("Github Issue 23 Part 1: address display error"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + next(); + }); + }); + }); +}); +}, -// Github Issue 23: Use correct derivation path when changing tabs -// https://github.com/dcpos/bip39/issues/23 +// Github Issue 23 Part 2: Coin selection in derivation path +// https://github.com/iancoleman/bip39/issues/23#issuecomment-238011920 +function() { +page.open(url, function(status) { + // set the phrase + page.evaluate(function() { + $(".phrase").val("abandon abandon ability").trigger("input"); + }); + waitForGenerate(function() { + // switch from bitcoin to clam + page.evaluate(function() { + $(".network").val("9").trigger("change"); + }); + waitForGenerate(function() { + // check derivation path is displayed correctly + var expected = "m/44'/23'/0'/0/0"; + var actual = page.evaluate(function() { + return $(".index:first").text(); + }); + if (actual != expected) { + console.log("Github Issue 23 Part 2: Coin in BIP44 derivation path is incorrect"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + next(); + }); + }); +}); +}, // Github Issue 26: When using a Root key derrived altcoins are incorrect -// https://github.com/dcpos/bip39/issues/26 +// https://github.com/iancoleman/bip39/issues/26 +function() { +page.open(url, function(status) { + // 1) 2) and 3) set the root key + page.evaluate(function() { + $(".root-key").val("xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi").trigger("input"); + }); + waitForGenerate(function() { + // 4) switch from bitcoin to viacoin + page.evaluate(function() { + $(".network").val("6").trigger("change"); + }); + waitForGenerate(function() { + // 5) ensure the derived address is correct + var expected = "Vq9Eq4N5SQnjqZvxtxzo7hZPW5XnyJsmXT"; + var actual = page.evaluate(function() { + return $(".address:first").text(); + }); + if (actual != expected) { + console.log("Github Issue 26: address is incorrect when changing networks and using root-key to derive"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + next(); + }); + }); +}); +}, + +// Selecting a language with no existing phrase should generate a phrase in +// that language. +function() { +page.open(url, function(status) { + // Select a language + // Need to manually simulate hash being set due to quirk between + // 'click' event triggered by javascript vs triggered by mouse. + // Perhaps look into page.sendEvent + // http://phantomjs.org/api/webpage/method/send-event.html + page.evaluate(function() { + window.location.hash = "#japanese"; + $("a[href='#japanese']").trigger("click"); + }); + waitForGenerate(function() { + // Check the mnemonic is in Japanese + var phrase = page.evaluate(function() { + return $(".phrase").val(); + }); + if (phrase.length <= 0) { + console.log("No Japanese phrase generated"); + fail(); + } + if (phrase.charCodeAt(0) < 128) { + console.log("First character of Japanese phrase is ascii"); + console.log("Phrase: " + phrase); + fail(); + } + next(); + }); +}); +}, + +// Selecting a language with existing phrase should update the phrase to use +// that language. +function() { +page.open(url, function(status) { + // Set the phrase to an English phrase. + page.evaluate(function() { + $(".phrase").val("abandon abandon ability").trigger("input"); + }); + waitForGenerate(function() { + // Change to Italian + // Need to manually simulate hash being set due to quirk between + // 'click' event triggered by javascript vs triggered by mouse. + // Perhaps look into page.sendEvent + // http://phantomjs.org/api/webpage/method/send-event.html + page.evaluate(function() { + window.location.hash = "#italian"; + $("a[href='#italian']").trigger("click"); + }); + waitForGenerate(function() { + // Check only the language changes, not the phrase + var expected = "abaco abaco abbaglio"; + var actual = page.evaluate(function() { + return $(".phrase").val(); + }); + if (actual != expected) { + console.log("Changing language with existing phrase"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + // Check the address is correct + var expected = "1Dz5TgDhdki9spa6xbPFbBqv5sjMrx3xgV"; + var actual = page.evaluate(function() { + return $(".address:first").text(); + }); + if (actual != expected) { + console.log("Changing language generates incorrect address"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + next(); + }); + }); +}); +}, + +// Suggested replacement for erroneous word in non-English language +function() { +page.open(url, function(status) { + // Set an incorrect phrase in Italian + page.evaluate(function() { + $(".phrase").val("abaco abaco zbbaglio").trigger("input"); + }); + waitForFeedback(function() { + // Check the suggestion is correct + var feedback = page.evaluate(function() { + return $(".feedback").text(); + }); + if (feedback.indexOf("did you mean abbaglio?") < 0) { + console.log("Incorrect Italian word does not show suggested replacement"); + console.log("Error: " + error); + fail(); + } + next(); + }); +}); +}, + + +// Japanese word does not break across lines. +// Point 2 from +// https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md#japanese +function() { +page.open(url, function(status) { + hasWordBreakCss = page.content.indexOf("word-break: keep-all;") > -1; + if (!hasWordBreakCss) { + console.log("Japanese words can break across lines mid-word"); + console.log("Check CSS for '.phrase { word-break: keep-all; }'"); + fail(); + } + // Run the next test + next(); +}); +}, + +// Language can be specified at page load using hash value in url +function() { +page.open(url, function(status) { + // Set the page hash as if it were on a fresh page load + page.evaluate(function() { + window.location.hash = "#japanese"; + }); + // Generate a random phrase + page.evaluate(function() { + $(".generate").trigger("click"); + }); + waitForGenerate(function() { + // Check the phrase is in Japanese + var phrase = page.evaluate(function() { + return $(".phrase").val(); + }); + if (phrase.length <= 0) { + console.log("No phrase generated using url hash"); + fail(); + } + if (phrase.charCodeAt(0) < 128) { + console.log("Language not detected from url hash on page load."); + console.log("Phrase: " + phrase); + fail(); + } + next(); + }); +}); +}, + +// Entropy unit tests +function() { +page.open(url, function(status) { + var response = page.evaluate(function() { + var e; + // binary entropy is detected + try { + e = Entropy.fromString("01010101"); + if (e.base.str != "binary") { + return "Binary entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // base6 entropy is detected + try { + e = Entropy.fromString("012345012345"); + if (e.base.str != "base 6") { + return "base6 entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // dice entropy is detected + try { + e = Entropy.fromString("123456123456"); + if (e.base.str != "base 6 (dice)") { + return "dice entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // base10 entropy is detected + try { + e = Entropy.fromString("0123456789"); + if (e.base.str != "base 10") { + return "base10 entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // hex entropy is detected + try { + e = Entropy.fromString("0123456789ABCDEF"); + if (e.base.str != "hexadecimal") { + return "hexadecimal entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // card entropy is detected + try { + e = Entropy.fromString("AC4DTHKS"); + if (e.base.str != "card") { + return "card entropy not detected correctly"; + } + } + catch (e) { + return e.message; + } + // entropy is case insensitive + try { + e = Entropy.fromString("aBcDeF"); + if (e.cleanStr != "aBcDeF") { + return "Entropy should not be case sensitive"; + } + } + catch (e) { + return e.message; + } + // dice entropy is converted to base6 + try { + e = Entropy.fromString("123456"); + if (e.cleanStr != "012345") { + return "Dice entropy is not automatically converted to base6"; + } + } + catch (e) { + return e.message; + } + // dice entropy is preferred to base6 if ambiguous + try { + e = Entropy.fromString("12345"); + if (e.base.str != "base 6 (dice)") { + return "dice not used as default over base 6"; + } + } + catch (e) { + return e.message; + } + // unused characters are ignored + try { + e = Entropy.fromString("fghijkl"); + if (e.cleanStr != "f") { + return "additional characters are not ignored"; + } + } + catch (e) { + return e.message; + } + // the lowest base is used by default + // 7 could be decimal or hexadecimal, but should be detected as decimal + try { + e = Entropy.fromString("7"); + if (e.base.str != "base 10") { + return "lowest base is not used"; + } + } + catch (e) { + return e.message; + } + // Leading zeros are retained + try { + e = Entropy.fromString("000A"); + if (e.cleanStr != "000A") { + return "Leading zeros are not retained"; + } + } + catch (e) { + return e.message; + } + // Leading zeros are correctly preserved for hex in binary string + try { + e = Entropy.fromString("2A"); + if (e.binaryStr != "00101010") { + return "Hex leading zeros are not correct in binary"; + } + } + catch (e) { + return e.message; + } + // Leading zeros are correctly preserved for base 6 in binary string + try { + e = Entropy.fromString("2"); + if (e.binaryStr != "010") { + return "Base 6 leading zeros are not correct in binary"; + } + } + catch (e) { + return e.message; + } + // Keyboard mashing results in weak entropy + // Despite being a long string, it's less than 30 bits of entropy + try { + e = Entropy.fromString("aj;se ifj; ask,dfv js;ifj"); + if (e.binaryStr.length >= 30) { + return "Keyboard mashing should produce weak entropy"; + } + } + catch (e) { + return e.message; + } + // Card entropy is used if every pair could be a card + try { + e = Entropy.fromString("4c3c2c"); + if (e.base.str != "card") { + return "Card entropy not used if all pairs are cards"; + } + } + catch (e) { + return e.message; + } + // Card entropy uses base 52 + // [ cards, binary ] + try { + var cards = [ + [ "ac", "00000" ], + [ "acac", "00000000000" ], + [ "acac2c", "00000000000000001" ], + [ "acks", "00000110011" ], + [ "acacks", "00000000000110011" ], + [ "2c", "000001" ], + [ "3d", "001111" ], + [ "4h", "011101" ], + [ "5s", "101011" ], + [ "6c", "000101" ], + [ "7d", "010011" ], + [ "8h", "100001" ], + [ "9s", "101111" ], + [ "tc", "001001" ], + [ "jd", "010111" ], + [ "qh", "100101" ], + [ "ks", "110011" ], + [ "ks2c", "101001011101" ], + [ "KS2C", "101001011101" ], + ]; + for (var i=0; i -1) { + console.log("Dice entropy value is shown instead of true base 6 value"); + fail(); + } + next(); + }); +}); +}, + +// The number of bits of entropy accumulated is shown +function() { +page.open(url, function(status) { + //[ entropy, bits ] + var tests = [ + [ "0000 0000 0000 0000 0000", "20" ], + [ "0", "1" ], + [ "0000", "4" ], + [ "6", "3" ], + [ "7", "4" ], + [ "8", "4" ], + [ "F", "4" ], + [ "29", "7" ], + [ "0A", "8" ], + [ "1A", "8" ], // hex is always multiple of 4 bits of entropy + [ "2A", "8" ], + [ "4A", "8" ], + [ "8A", "8" ], + [ "FA", "8" ], + [ "000A", "16" ], + [ "2220", "11" ], + [ "2221", "11" ], // uses dice, so entropy is actually 1110 + [ "2227", "14" ], + [ "222F", "16" ], + [ "FFFF", "16" ], + ] + // use entropy + page.evaluate(function(e) { + $(".use-entropy").prop("checked", true).trigger("change"); + }); + // Run each test + var nextTest = function runNextTest(i) { + var entropy = tests[i][0]; + var expected = tests[i][1]; + // set entropy + page.evaluate(function(e) { + $(".entropy").val(e).trigger("input"); + }, entropy); + // check the number of bits of entropy is shown + waitForEntropyFeedback(function() { + var entropyText = page.evaluate(function() { + return $(".entropy-error").text(); + }); + if (entropyText.indexOf("Have " + expected + " bits of entropy") == -1) { + console.log("Accumulated entropy is not shown correctly for " + entropy); + console.log(entropyText); + fail(); + } + var isLastTest = i == tests.length - 1; + if (isLastTest) { + next(); + } + else { + runNextTest(i+1); + } + }); + } + nextTest(0); +}); +}, + +// The number of bits of entropy to reach the next mnemonic strength is shown +function() { +page.open(url, function(status) { + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + $(".entropy").val("7654321").trigger("input"); + }); + // check the amount of additional entropy required is shown + waitForEntropyFeedback(function() { + var entropyText = page.evaluate(function() { + return $(".entropy-container").text(); + }); + if (entropyText.indexOf("3 more base 10 chars required") == -1) { + console.log("Additional entropy requirement is not shown"); + fail(); + } + next(); + }); +}); +}, + +// The next strength above 0-word mnemonics is considered extremely weak +// The next strength above 3-word mnemonics is considered very weak +// The next strength above 6-word mnemonics is considered weak +// The next strength above 9-word mnemonics is considered strong +// The next strength above 12-word mnemonics is considered very strong +// The next strength above 15-word mnemonics is considered extremely strong +function() { +page.open(url, function(status) { + var tests = [ + { + entropy: "A", + words: 0, + nextStrength: "an extremely weak", + }, + { + entropy: "AAAAAAAA", + words: 3, + nextStrength: "a very weak", + }, + { + entropy: "AAAAAAAA B", + words: 3, + nextStrength: "a very weak", + }, + { + entropy: "AAAAAAAA BBBBBBBB", + words: 6, + nextStrength: "a weak", + }, + { + entropy: "AAAAAAAA BBBBBBBB CCCCCCCC", + words: 9, + nextStrength: "a strong", + }, + { + entropy: "AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD", + words: 12, + nextStrength: "a very strong", + }, + { + entropy: "AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE", + words: 15, + nextStrength: "an extremely strong", + } + ]; + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + }); + var nextTest = function runNextTest(i) { + test = tests[i]; + page.evaluate(function(e) { + $(".addresses").empty(); + $(".phrase").val(""); + $(".entropy").val(e).trigger("input"); + }, test.entropy); + if (test.words == 0) { + var mnemonic = page.evaluate(function() { + return $(".phrase").val(); + }); + if (mnemonic.length > 0) { + console.log("Mnemonic length for " + test.nextStrength + " strength is not " + test.words); + console.log("Mnemonic: " + mnemonic); + fail(); + } + var isLastTest = i == tests.length - 1; + if (isLastTest) { + next(); + } + else { + runNextTest(i+1); + } + } + else { + waitForGenerate(function() { + // check the strength of the current mnemonic + var mnemonic = page.evaluate(function() { + return $(".phrase").val(); + }); + if (mnemonic.split(" ").length != test.words) { + console.log("Mnemonic length for " + test.nextStrength + " strength is not " + test.words); + console.log("Mnemonic: " + mnemonic); + fail(); + } + // check the strength of the next mnemonic is shown + var entropyText = page.evaluate(function() { + return $(".entropy-container").text(); + }); + if (entropyText.indexOf("required to generate " + test.nextStrength + " mnemonic") == -1) { + console.log("Strength indicator for " + test.nextStrength + " mnemonic is incorrect"); + fail(); + } + var isLastTest = i == tests.length - 1; + if (isLastTest) { + next(); + } + else { + runNextTest(i+1); + } + }); + } + } + nextTest(0); +}); +}, + +// Entropy is truncated from the right +function() { +page.open(url, function(status) { + var expected = "abandon abandon ability"; + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + var entropy = "00000000 00000000 00000000 00000000"; + entropy += "11111111 11111111 11111111 1111"; // Missing last byte, only first 8 bytes are used + $(".entropy").val(entropy).trigger("input"); + }); + // check the entropy is truncated from the right + waitForGenerate(function() { + var actual = page.evaluate(function() { + return $(".phrase").val(); + }); + if (actual != expected) { + console.log("Entropy is not truncated from the right"); + console.log("Expected: " + expected); + console.log("Got: " + actual); + fail(); + } + next(); + }); +}); +}, + +// Very large entropy results in very long mnemonics +function() { +page.open(url, function(status) { + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + var entropy = ""; + // Generate a very long entropy string + for (var i=0; i<33; i++) { + entropy += "AAAAAAAA"; // 3 words * 33 iterations = 99 words + } + $(".entropy").val(entropy).trigger("input"); + }); + // check the mnemonic is very long + waitForGenerate(function() { + var wordCount = page.evaluate(function() { + return $(".phrase").val().split(" ").length; + }); + if (wordCount != 99) { + console.log("Large entropy does not generate long mnemonic"); + console.log("Expected 99 words, got " + wordCount); + fail(); + } + next(); + }); +}); +}, + +// Is compatible with bip32jp entropy +// https://bip32jp.github.io/english/index.html +// NOTES: +// Is incompatible with: +// base 6 with leading zeros +// base 6 wth 12 words / 53 chars +// base 20 +function() { +page.open(url, function(status) { + var expected = "defy trip fatal jaguar mean rack rifle survey satisfy drift twist champion steel wife state furnace night consider glove olympic oblige donor novel left"; + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + var entropy = "123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123450123"; + $(".entropy").val(entropy).trigger("input"); + }); + // check the mnemonic matches the expected value from bip32jp + waitForGenerate(function() { + var actual = page.evaluate(function() { + return $(".phrase").val(); + }); + if (actual != expected) { + console.log("Mnemonic does not match bip32jp for base 6 entropy"); + console.log("Expected: " + expected); + console.log("Got: " + actual); + fail(); + } + next(); + }); +}); +}, + +// Blank entropy does not generate mnemonic or addresses +function() { +page.open(url, function(status) { + // use entropy + page.evaluate(function() { + $(".use-entropy").prop("checked", true).trigger("change"); + $(".entropy").val("").trigger("input"); + }); + waitForFeedback(function() { + // check there is no mnemonic + var phrase = page.evaluate(function() { + return $(".phrase").val(); + }); + if (phrase != "") { + console.log("Blank entropy does not result in blank mnemonic"); + console.log("Got: " + phrase); + fail(); + } + // check there are no addresses displayed + var addresses = page.evaluate(function() { + return $(".address").length; + }); + if (addresses != 0) { + console.log("Blank entropy does not result in zero addresses"); + fail(); + } + // Check the feedback says 'blank entropy' + var feedback = page.evaluate(function() { + return $(".feedback").text(); + }); + if (feedback != "Blank entropy") { + console.log("Blank entropy does not show feedback message"); + fail(); + } + next(); + }); +}); +}, + +// If you wish to add more tests, do so here... + +// Here is a blank test template +/* + +function() { +page.open(url, function(status) { + // Do something on the page + page.evaluate(function() { + $(".phrase").val("abandon abandon ability").trigger("input"); + }); + waitForGenerate(function() { + // Check the result of doing the thing + var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug"; + var actual = page.evaluate(function() { + return $(".address:first").text(); + }); + if (actual != expected) { + console.log("A specific message about what failed"); + console.log("Expected: " + expected); + console.log("Actual: " + actual); + fail(); + } + // Run the next test + next(); + }); +}); +}, + +*/ ];