diff options
| author | Stephen Blott | 2015-01-19 05:39:24 +0000 |
|---|---|---|
| committer | Stephen Blott | 2015-01-20 06:50:08 +0000 |
| commit | 97e61e29d59b9557fe1fb8d7ae1a34be1d47fcc1 (patch) | |
| tree | b989b02071fc736a798cf472287a8a1c40b7dfff /tests | |
| parent | 9fa664167b5aaf99069ba9298646a39853eeb067 (diff) | |
| download | vimium-97e61e29d59b9557fe1fb8d7ae1a34be1d47fcc1.tar.bz2 | |
Rework DOM tests.
- Set up modes such that they can be re-initialised.
- Move initialisation of BadgeMode to general initialisation function.
- Add reset() method for handlerStack.
- Consistently use initializeModeState() in all tests' setup().
- Refactor focusInput tests.
- Add some more tests.
- Simplify some other tests.
Note: Clean-up of the inputFocus overlay now happens when the exit()
method is called in Mode.reset(). This eliminates most needs to
artificially bubble a keyboard event to clear the overlay.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/dom_tests/chrome.coffee | 5 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.coffee | 301 |
2 files changed, 145 insertions, 161 deletions
diff --git a/tests/dom_tests/chrome.coffee b/tests/dom_tests/chrome.coffee index ad4ae74b..2e7c6a5a 100644 --- a/tests/dom_tests/chrome.coffee +++ b/tests/dom_tests/chrome.coffee @@ -3,6 +3,9 @@ # root = exports ? window +root.chromeMessages = [] + +document.hasFocus = -> true root.chrome = { runtime: { @@ -18,7 +21,7 @@ root.chrome = { onMessage: { addListener: -> } - sendMessage: -> + sendMessage: (message) -> chromeMessages.unshift message getManifest: -> getURL: (url) -> "../../#{url}" } diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index a4713a72..8cae8289 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -12,18 +12,22 @@ mockKeyboardEvent = (keyChar) -> event.preventDefault = -> @suppressed = true event -# Some of these tests have side effects on the handler stack and active mode. Therefore, we take backups and -# restore them on tear down. -backupStackState = -> - Mode.backup = Mode.modes[..] - InsertMode.permanentInstance.exit() - handlerStack.backup = handlerStack.stack[..] -restoreStackState = -> - for mode in Mode.modes - mode.exit() unless mode in Mode.backup - Mode.modes = Mode.backup - InsertMode.permanentInstance.exit() - handlerStack.stack = handlerStack.backup +# Some tests have side effects on the handler stack and the active mode, so these are reset as necessary. +initializeModeState = -> + Mode.reset() + handlerStack.reset() + initializeModes() + # We use "m" as the only mapped key, "p" as a passkey (sometimes), and "u" as an unmapped key. + refreshCompletionKeys + completionKeys: "mp" + handlerStack.bubbleEvent "registerStateChange", + enabled: true + passKeys: "" + handlerStack.bubbleEvent "registerKeyQueue", + keyQueue: "" + +# Install event handlers. +initializeWhenEnabled() # # Retrieve the hint markers as an array object. @@ -40,6 +44,7 @@ createGeneralHintTests = (isFilteredMode) -> context "Link hints", setup -> + initializeModeState() testContent = "<a>test</a>" + "<a>tress</a>" document.getElementById("test-div").innerHTML = testContent stub settings.values, "filterLinkHints", false @@ -77,6 +82,7 @@ createGeneralHintTests true context "Alphabetical link hints", setup -> + initializeModeState() stub settings.values, "filterLinkHints", false stub settings.values, "linkHintCharacters", "ab" @@ -112,6 +118,7 @@ context "Filtered link hints", context "Text hints", setup -> + initializeModeState() testContent = "<a>test</a>" + "<a>tress</a>" + "<a>trait</a>" + "<a>track<img alt='alt text'/></a>" document.getElementById("test-div").innerHTML = testContent LinkHints.init() @@ -139,6 +146,7 @@ context "Filtered link hints", context "Image hints", setup -> + initializeModeState() testContent = "<a><img alt='alt text'/></a><a><img alt='alt text' title='some title'/></a> <a><img title='some title'/></a>" + "<a><img src='' width='320px' height='100px'/></a>" document.getElementById("test-div").innerHTML = testContent @@ -158,6 +166,7 @@ context "Filtered link hints", context "Input hints", setup -> + initializeModeState() testContent = "<input type='text' value='some value'/><input type='password' value='some value'/> <textarea>some text</textarea><label for='test-input'/>a label</label> <input type='text' id='test-input' value='some value'/> @@ -180,39 +189,44 @@ context "Filtered link hints", context "Input focus", setup -> + initializeModeState() testContent = "<input type='text' id='first'/><input style='display:none;' id='second'/> <input type='password' id='third' value='some value'/>" document.getElementById("test-div").innerHTML = testContent - backupStackState() tearDown -> document.getElementById("test-div").innerHTML = "" - restoreStackState() - should "focus the right element", -> + should "focus the first element", -> focusInput 1 assert.equal "first", document.activeElement.id + should "focus the nth element", -> focusInput 100 assert.equal "third", document.activeElement.id - handlerStack.bubbleEvent 'keydown', mockKeyboardEvent("A") - # This is the same as above, but also verifies that focusInput activates insert mode. - should "activate insert mode", -> + should "activate insert mode on the first element", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() focusInput 1 - handlerStack.bubbleEvent 'focus', target: document.activeElement assert.isTrue InsertMode.permanentInstance.isActive() + should "activate insert mode on the first element", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() focusInput 100 - handlerStack.bubbleEvent 'focus', target: document. activeElement assert.isTrue InsertMode.permanentInstance.isActive() should "select the previously-focused input when count is 1", -> - focusInput 100 - handlerStack.bubbleEvent 'focus', target: document. activeElement + document.getElementById("third").focus() + document.getElementById("third").blur() focusInput 1 assert.equal "third", document.activeElement.id + should "not trigger insert if there are no inputs", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() + document.getElementById("test-div").innerHTML = "" + focusInput 1 + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() + # TODO: these find prev/next link tests could be refactored into unit tests which invoke a function which has # a tighter contract than goNext(), since they test minor aspects of goNext()'s link matching behavior, and we # don't need to construct external state many times over just to test that. @@ -222,6 +236,7 @@ context "Input focus", context "Find prev / next links", setup -> + initializeModeState() window.location.hash = "" should "find exact matches", -> @@ -281,19 +296,14 @@ createLinks = (n) -> # For these tests, we use "m" as a mapped key, "p" as a pass key, and "u" as an unmapped key. context "Normal mode", setup -> - document.activeElement?.blur() - backupStackState() - refreshCompletionKeys - completionKeys: "m" - - tearDown -> - restoreStackState() + initializeModeState() should "suppress mapped keys", -> - for event in [ "keydown", "keypress", "keyup" ] - key = mockKeyboardEvent "m" - handlerStack.bubbleEvent event, key - assert.isTrue key.suppressed + for k in [ "m", "p" ] + for event in [ "keydown", "keypress", "keyup" ] + key = mockKeyboardEvent "p" + handlerStack.bubbleEvent event, key + assert.isTrue key.suppressed should "not suppress unmapped keys", -> for event in [ "keydown", "keypress", "keyup" ] @@ -303,67 +313,29 @@ context "Normal mode", context "Passkeys mode", setup -> - backupStackState() - refreshCompletionKeys - completionKeys: "mp" - - handlerStack.bubbleEvent "registerStateChange", - enabled: true - passKeys: "" - - handlerStack.bubbleEvent "registerKeyQueue", - keyQueue: "" - - tearDown -> - restoreStackState() - handlerStack.bubbleEvent "registerStateChange", - enabled: true - passKeys: "" - - handlerStack.bubbleEvent "registerKeyQueue", - keyQueue: "" - - should "not suppress passKeys", -> - # First check normal-mode key (just to verify the framework). - for k in [ "m", "p" ] - for event in [ "keydown", "keypress", "keyup" ] - key = mockKeyboardEvent "p" - handlerStack.bubbleEvent event, key - assert.isTrue key.suppressed - - # Install passKey. + initializeModeState() handlerStack.bubbleEvent "registerStateChange", enabled: true passKeys: "p" - # Then verify passKey. + should "not suppress passKeys, but suppress other mapped keys", -> + # Verify passKey. for event in [ "keydown", "keypress", "keyup" ] key = mockKeyboardEvent "p" handlerStack.bubbleEvent event, key assert.isFalse key.suppressed - # And re-verify a mapped key. + # Verify mapped key. for event in [ "keydown", "keypress", "keyup" ] key = mockKeyboardEvent "m" handlerStack.bubbleEvent event, key assert.isTrue key.suppressed should "suppress passKeys with a non-empty keyQueue", -> - # Install passKey. - handlerStack.bubbleEvent "registerStateChange", - enabled: true - passKeys: "p" - - # First check the key is indeed not suppressed. - for event in [ "keydown", "keypress", "keyup" ] - key = mockKeyboardEvent "p" - handlerStack.bubbleEvent event, key - assert.isFalse key.suppressed - handlerStack.bubbleEvent "registerKeyQueue", - keyQueue: "1" + keyQueue: "p" - # Now verify that the key is suppressed. + # Verify that the passKey is indeed now suppressed. for event in [ "keydown", "keypress", "keyup" ] key = mockKeyboardEvent "p" handlerStack.bubbleEvent event, key @@ -371,13 +343,7 @@ context "Passkeys mode", context "Insert mode", setup -> - document.activeElement?.blur() - backupStackState() - refreshCompletionKeys - completionKeys: "m" - - tearDown -> - backupStackState() + initializeModeState() should "not suppress mapped keys in insert mode", -> # First verify normal-mode key (just to verify the framework). @@ -387,8 +353,7 @@ context "Insert mode", assert.isTrue key.suppressed # Install insert mode. - insertMode = new InsertMode - global: true + insertMode = new InsertMode global: true # Then verify insert mode. for event in [ "keydown", "keypress", "keyup" ] @@ -406,57 +371,53 @@ context "Insert mode", context "Triggering insert mode", setup -> - document.activeElement?.blur() - backupStackState() - refreshCompletionKeys - completionKeys: "m" + initializeModeState() testContent = "<input type='text' id='first'/> <input style='display:none;' id='second'/> - <input type='password' id='third' value='some value'/>" + <input type='password' id='third' value='some value'/> + <p id='fourth' contenteditable='true'/> + <p id='fifth'/>" document.getElementById("test-div").innerHTML = testContent tearDown -> - restoreStackState() + document.activeElement?.blur() document.getElementById("test-div").innerHTML = "" should "trigger insert mode on focus of contentEditable elements", -> - handlerStack.bubbleEvent "focus", - target: - isContentEditable: true - + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() + document.getElementById("fourth").focus() assert.isTrue Mode.top().name == "insert" and Mode.top().isActive() should "trigger insert mode on focus of text input", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() document.getElementById("first").focus() - handlerStack.bubbleEvent "focus", { target: document.activeElement } - assert.isTrue Mode.top().name == "insert" and Mode.top().isActive() should "trigger insert mode on focus of password input", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() document.getElementById("third").focus() - handlerStack.bubbleEvent "focus", { target: document.activeElement } - assert.isTrue Mode.top().name == "insert" and Mode.top().isActive() + should "not trigger insert mode on other elements", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() + document.getElementById("fifth").focus() + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() + should "not handle suppressed events", -> + assert.isTrue Mode.top().name == "insert" and not Mode.top().isActive() document.getElementById("first").focus() - handlerStack.bubbleEvent "focus", { target: document.activeElement } assert.isTrue Mode.top().name == "insert" and Mode.top().isActive() for event in [ "keydown", "keypress", "keyup" ] - # Because "m" is mapped, we expect insert mode to ignore it, and normal mode to suppress it. key = mockKeyboardEvent "m" InsertMode.suppressEvent key handlerStack.bubbleEvent event, key assert.isTrue key.suppressed - context "Mode utilities", setup -> - backupStackState() - refreshCompletionKeys - completionKeys: "m" + initializeModeState() testContent = "<input type='text' id='first'/> <input style='display:none;' id='second'/> @@ -464,7 +425,6 @@ context "Mode utilities", document.getElementById("test-div").innerHTML = testContent tearDown -> - restoreStackState() document.getElementById("test-div").innerHTML = "" should "not have duplicate singletons", -> @@ -491,13 +451,14 @@ context "Mode utilities", escape = keyCode: 27 + assert.isTrue Mode.top().name == "insert" new Mode exitOnEscape: true name: "test" assert.isTrue Mode.top().name == "test" handlerStack.bubbleEvent "keydown", escape - assert.isTrue Mode.top().name != "test" + assert.isTrue Mode.top().name == "insert" should "not exit on escape if not enabled", -> escape = @@ -505,6 +466,7 @@ context "Mode utilities", keyIdentifier: "" stopImmediatePropagation: -> + assert.isTrue Mode.top().name == "insert" new Mode exitOnEscape: false name: "test" @@ -517,25 +479,27 @@ context "Mode utilities", element = document.getElementById("first") element.focus() + assert.isTrue Mode.top().name == "insert" new Mode exitOnBlur: element name: "test" assert.isTrue Mode.top().name == "test" - handlerStack.bubbleEvent "blur", { target: element } - assert.isTrue Mode.top().name != "test" + element.blur() + assert.isTrue Mode.top().name == "insert" - should "not exit on blur if not enabled", -> - element = document.getElementById("first") - element.focus() + should "not exit on blur if not enabled", -> + element = document.getElementById("first") + element.focus() - new Mode - exitOnBlur: null - name: "test" + assert.isTrue Mode.top().name == "insert" + new Mode + exitOnBlur: null + name: "test" - assert.isTrue Mode.top().name == "test" - handlerStack.bubbleEvent "blur", { target: element } - assert.isTrue Mode.top().name == "test" + assert.isTrue Mode.top().name == "test" + element.blur() + assert.isTrue Mode.top().name == "test" should "register state change", -> enabled = null @@ -546,21 +510,17 @@ context "Mode utilities", super trackState: true - registerStateChange: -> - enabled = @enabled - passKeys = @passKeys - - new Test() + test = new Test() handlerStack.bubbleEvent "registerStateChange", enabled: "enabled" passKeys: "passKeys" - assert.isTrue enabled == "enabled" - assert.isTrue passKeys == "passKeys" + + assert.isTrue test.enabled == "enabled" + assert.isTrue test.passKeys == "passKeys" should "suppress printable keys", -> element = document.getElementById("first") element.focus() - handlerStack.bubbleEvent "focus", { target: document.activeElement } # Verify that a key is not suppressed. for event in [ "keydown", "keypress", "keyup" ] @@ -595,9 +555,7 @@ context "Mode utilities", context "PostFindMode", setup -> - backupStackState() - refreshCompletionKeys - completionKeys: "m" + initializeModeState() testContent = "<input type='text' id='first'/> <input style='display:none;' id='second'/> @@ -612,15 +570,11 @@ context "PostFindMode", @element = document.getElementById("first") @element.focus() - handlerStack.bubbleEvent "focus", { target: document.activeElement } tearDown -> - restoreStackState() document.getElementById("test-div").innerHTML = "" should "be a singleton", -> - count = 0 - assert.isTrue Mode.top().name == "insert" new PostFindMode @element assert.isTrue Mode.top().name == "post-find" @@ -630,30 +584,29 @@ context "PostFindMode", assert.isTrue Mode.top().name == "insert" should "suppress unmapped printable keypress events", -> + testKeys = (verify) -> + for event in [ "keydown", "keypress", "keyup" ] + key = mockKeyboardEvent "u" + handlerStack.bubbleEvent event, + extend key, + srcElement: @element + verify key.suppressed + # Verify key is passed through. - for event in [ "keydown", "keypress", "keyup" ] - key = mockKeyboardEvent "u" - handlerStack.bubbleEvent event, key - assert.isFalse key.suppressed + testKeys assert.isFalse - new PostFindMode @element + new PostFindMode # Verify key is now suppressed for keypress. - key = mockKeyboardEvent "u" - handlerStack.bubbleEvent "keypress", - extend key, - srcElement: @element - assert.isTrue key.suppressed + testKeys assert.isTrue should "be clickable to focus", -> new PostFindMode @element - assert.isTrue Mode.top().name != "insert" - handlerStack.bubbleEvent "click", { target: document.activeElement } + handlerStack.bubbleEvent "click", target: document.activeElement assert.isTrue Mode.top().name == "insert" should "enter insert mode on immediate escape", -> - new PostFindMode @element assert.isTrue Mode.top().name == "post-find" handlerStack.bubbleEvent "keydown", @escape @@ -668,33 +621,61 @@ context "PostFindMode", context "Mode badges", setup -> - backupStackState() + initializeModeState() + + testContent = "<input type='text' id='first'/> + <input style='display:none;' id='second'/> + <input type='password' id='third' value='some value'/>" + document.getElementById("test-div").innerHTML = testContent tearDown -> - restoreStackState() + document.getElementById("test-div").innerHTML = "" should "have no badge without passKeys", -> - handlerStack.bubbleEvent "registerStateChange", - enabled: true - passKeys: "" - - handlerStack.bubbleEvent "updateBadge", badge = { badge: "" } - assert.isTrue badge.badge == "" + Mode.updateBadge() + assert.isTrue chromeMessages[0].badge == "" should "have no badge with passKeys", -> handlerStack.bubbleEvent "registerStateChange", enabled: true passKeys: "p" + Mode.updateBadge() + assert.isTrue chromeMessages[0].badge == "" + + should "have an I badge in insert mode by focus", -> + document.getElementById("first").focus() + assert.isTrue chromeMessages[0].badge == "I" + + should "have no badge after insert mode by focus", -> + document.getElementById("first").focus() + document.getElementById("first").blur() + assert.isTrue chromeMessages[0].badge == "" + + should "have an I badge in global insert mode", -> + new InsertMode global: true + assert.isTrue chromeMessages[0].badge == "I" - handlerStack.bubbleEvent "updateBadge", badge = { badge: "" } - assert.isTrue badge.badge == "" + should "have no badge after global insert mode", -> + mode = new InsertMode global: true + mode.exit() + assert.isTrue chromeMessages[0].badge == "" + + should "have a ? badge in PostFindMode (immediately)", -> + document.getElementById("first").focus() + new PostFindMode + assert.isTrue chromeMessages[0].badge == "?" + + should "have no badge in PostFindMode (subsequently)", -> + document.getElementById("first").focus() + new PostFindMode + handlerStack.bubbleEvent "keydown", mockKeyboardEvent "u" + assert.isTrue chromeMessages[0].badge == "" should "have no badge when disabled", -> handlerStack.bubbleEvent "registerStateChange", enabled: false passKeys: "" - new InsertMode() - handlerStack.bubbleEvent "updateBadge", badge = { badge: "" } - assert.isTrue badge.badge == "" + element = document.getElementById("first").focus() + assert.isTrue chromeMessages[0].badge == "" |
