17

Ich bin versuchen, den aktuell ausgewählten Text in einem Eingang zu bekommen mit window.getSelection() aber ich bin immer einen leeren String bekommen:zur Zeit Text ausgewählt Erste

expect(browser.executeScript("return window.getSelection().toString();")).toEqual("test"); 

Ergebnisse in:

Expected '' to equal 'test'. 

Die mit angularjs.org als Zielstelle reproduzierbare Testabwicklung:

describe("My test", function() { 
    beforeEach(function() { 
     browser.get("https://angularjs.org/"); 
    }); 

    it("should select text in an input", function() { 
     var query = element(by.css("input.search-query")); 
     query.sendKeys("test"); 
     query.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a")); 

     expect(browser.executeScript("return window.getSelection().toString();")).toEqual("test"); 
    }); 
}); 

Beachten Sie, dass ich actuall y sehen Sie den eingegebenen Text mit COMMAND + "a" ausgewählt.

Was mache ich falsch?

Winkelmesser Mit 2.5.1, firefox 41.

Antwort

16

getSelection funktioniert nicht Text in input Elemente ausgewählt, aber für auf Elemente auf der Seite getroffenen Auswahl.

Sie könnten selectionStart und selectionEnd wie folgt verwenden:

return document.activeElement.value.substring(
    document.activeElement.selectionStart, 
    document.activeElement.selectionEnd) 

Sie wahrscheinlich eine Funktion für diese Stelle dieses Einzeiler schaffen sollte. Und vielleicht wollen Sie dann auch zu prüfen, ob document.activeElement ist in der Tat die richtige Art von Element, etc. Und wenn Sie schon dabei sind, können Sie es sogar für Pre-IE9-Browser kompatibel machen ... (difficult though)

Einfache Funktion

Dies funktioniert auch auf input oder textarea Kontrollen, die den Fokus nicht haben:

function getInputSelection(el) { 
    if (el.selectionStart !== undefined) { 
     return el.value.substring(el.selectionStart, el.selectionEnd); 
    } 
} 
// Example call: 
console.log(getInputSelection(document.activeElement)); 

Umfangreiche jQuery-Plug-in

Dies sorgt für mehr browserübergreifende Kompatibilität (vor IE9) und unterstützt nicht nur das Abrufen, sondern auch das Festlegen von Auswahlbereich und Text in Form eines jQuery Plug-ins. Es befasst sich mit der Tatsache, dass CRLF Zeichenfolgen als eine Zeichenposition auf pragmatische Weise zählen (ersetzen durch LF nur in-place):

/** 
* jQuery plug-in for getting/setting the selection range and text 
* within input/textarea element(s). When the selection is set, 
* the element will receive focus. When getting the selection, 
* some browsers require the element to have focus (IE8 and below). 
* It is up to the caller to set the focus first, if so needed. 
* @this {jQuery} Input/textarea element(s). 
* @param {object} opt_bounds When provided, it sets the range as follows: 
* @param {number} opt_bounds.start Optional start of the range. If not 
* provided, the start point of the range is not altered. 
* @param {number} opt_bounds.end Optional end of the range. If not 
* provided, the end point of the range is not altered. If null, the end 
* of the text value is assumed. 
* @param {number} opt_bounds.text Optional text to put in the range. If 
* not provided, no change will be made to the range's text. 
* @return {jQuery|object|undefined} When setting: the same as @this to 
* allow chaining, when getting, an object {start, end, text, length} 
* representing the selection in the first element if that info 
* is available, undefined otherwise. 
*/ 
$.fn.selection = function (opt_bounds) { 
    var bounds, inputRange, input, docRange, value; 

    function removeCR(s) { 
     // CRLF counts as one unit in text box, so replace with 1 char 
     // for correct offsetting 
     return s.replace(/\r\n/g, '\n'); 
    } 

    if (opt_bounds === undefined) { 
     // Get 
     if (!this.length) { 
      return; 
     } 
     bounds = {}; 
     input = this[0]; 
     if (input.setSelectionRange) { 
      // Modern browsers 
      bounds.start = input.selectionStart; 
      bounds.end = input.selectionEnd; 
     } else { 
      // Check browser support 
      if (!document.selection || !document.selection.createRange) { 
       return; 
      } 
      // IE8 or older 
      docRange = document.selection.createRange(); 
      // Selection must be confined to input only 
      if (!docRange || docRange.parentElement() !== input) { return; } 
      // Create another range that can only extend within the 
      // input boundaries. 
      inputRange = input.createTextRange(); 
      inputRange.moveToBookmark(docRange.getBookmark()); 
      // Measure how many characters we can go back within the input: 
      bounds.start = 
       -inputRange.moveStart('character', -input.value.length); 
      bounds.end = -inputRange.moveEnd('character', -input.value.length); 
     } 
     // Add properties: 
     bounds.length = bounds.end - bounds.start; 
     bounds.text = removeCR(input.value). 
      substr(bounds.start, bounds.length); 
     return bounds; 
    } 
    // Set 
    if (opt_bounds.text !== undefined) { 
     opt_bounds.text = removeCR(opt_bounds.text); 
    } 
    return this.each(function() { 
     bounds = $.extend($(this).selection(), opt_bounds); 
     bounds.end = bounds.end === null ? this.value.length : bounds.end; 
     if (opt_bounds.text !== undefined) { 
      value = removeCR(this.value); 
      this.value = value.substr(0, bounds.start) + bounds.text + 
       value.substr(bounds.end); 
      bounds.end = bounds.start + bounds.text.length; 
     } 
     if (this.setSelectionRange) { 
      // Modern browsers 
      // Call .focus() to align with IE8 behaviour. 
      // You can leave that out if you don't care about that. 
      this.focus(); 
      this.setSelectionRange(bounds.start, bounds.end); 
     } else if (this.createTextRange) { 
      // IE8 and before 
      inputRange = this.createTextRange(); 
      inputRange.collapse(true); 
      inputRange.moveEnd('character', bounds.end); 
      inputRange.moveStart('character', bounds.start); 
      // .select() will also focus the element: 
      inputRange.select(); 
     } 
    }); 
}; 

Beispiel für die Verwendung:

// Get 
console.log($('textarea').selection().text); 
// Set text 
$('textarea').selection({text: "Hello!"}); 
// Set starting point of selection 
$('textarea').selection({start: 1}); 
+2

Yup, hier ist das, was ich habe schließlich endete mit: 'expect (browser.executeScript (" return arguments [0] .value.substring (Argumente [0] .selectionStart, Argumente [0] .selectionEnd); ", query.getWebElement())). toEqual ("Test"); '. Vielen Dank! – alecxe

+0

wusste nicht einmal über diese Funktion. Sehr cool! –

Verwandte Themen