17

Я пытаюсь получить выбранный текст входа с помощью window.getSelection(), но я всегда получаю пустую строку:Начало текущего выбранного текста

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

Результаты в:

Expected '' to equal 'test'. 

полный воспроизводимый тест с использованием angularjs.org в качестве целевого сайта:

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"); 
    }); 
}); 

Обратите внимание, что я являюсь актуалом y см. введенный текст, выбранный с помощью COMMAND + «a».

Что я делаю неправильно?

Использование транспортира 2.5.1, Firefox 41.

ответ

16

getSelection не работает для текста, выбранного в input элементов, но и для выбора, сделанного на элементах по всей странице.

Вы можете использовать selectionStart и selectionEnd так:

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

Вы должны, вероятно, создать функцию для этого вместо этого однострочника. А может быть, вы хотите, чтобы затем также проверить, является ли document.activeElement действительно правильный тип элемента и т.д. И когда вы на него, вы можете даже сделать его совместимым для предварительного IE9 браузеры ... (difficult though)

Простой Функция

Это также будет работать на input или textarea управления, которые не имеют фокус:

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

Обширный JQuery плагин в

Это обеспечивает более кросс-браузерную совместимость (pre-IE9) и поддерживает не только получение, но и установку диапазона выбора и текста в виде плагина jQuery. Речь идет о том, что подсчет последовательностей CRLF символов в один символ прагматично (заменить на месте по LF только):

/** 
* 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(); 
     } 
    }); 
}; 

Пример использования:

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

Да, вот что я В итоге в итоге получилось: ожидать (browser.executeScript ("return arguments [0] .value.substring (arguments [0] .selectionStart, arguments [0] .selectionEnd);", query.getWebElement())). toEqual ("тест"); '. Спасибо! – alecxe

+0

Даже не знал об этой функции. Очень круто! –