Как выбрать параметр в выпадающем protractorjs Е2Е тестов


Я пытаюсь выбрать опцию из выпадающего списка для угловых тестов e2e с помощью транспортира.

вот фрагмент кода опции select:

<select id="locregion" class="create_select ng-pristine ng-invalid ng-invalid-required" required="" ng-disabled="organization.id !== undefined" ng-options="o.id as o.name for o in organizations" ng-model="organization.parent_id">
    <option value="?" selected="selected"></option>
    <option value="0">Ranjans Mobile Testing</option>
    <option value="1">BeaverBox Testing</option>
    <option value="2">BadgerBox</option>
    <option value="3">CritterCase</option>
    <option value="4">BoxLox</option>
    <option value="5">BooBoBum</option>
</select>

Я пробовал:

ptor.findElement(protractor.By.css('select option:1')).click();

это дает мне следующую ошибку:

была указана недопустимая или незаконная строка Информация о сборке: версия: '2.35.0', редакция: 'c916b9d', время: '2013-08-12 15: 42: 01' Информация о системе: os.name: 'Mac OS X', os.arch:' x86_64', os.версия: '10.9', java.версия: '1.6.0_65' Информация о драйвере: драйвер.версия: неизвестно!--4-->

Я тоже пробовал:

ptor.findElement(protractor.By.xpath('/html/body/div[2]/div/div[4]/div/div/div/div[3]/ng-include/div/div[2]/div/div/organization-form/form/div[2]/select/option[3]')).click();

это дает мне следующую ошибку:

ElementNotVisibleError: элемент в настоящее время не виден и поэтому не может взаимодействовать с Длительность команды или тайм-аут: 9 миллисекунд Информация о сборке: версия: '2.35.0', редакция: 'c916b9d', время: '2013-08-12 15: 42: 01' Информация о системе: os.name: 'Mac OS X', os.арка: 'x86_64 с', ОС.версия:' 10.9', java.версия: '1.6.0_65' Идентификатор сеанса: bdeb8088 - d8ad-0f49-aad9-82201c45c63f Информация о драйвере: org.openqa.селен.браузер firefox.FirefoxDriver Возможности [{платформа=МАК, acceptSslCerts=правда, javascriptEnabled=правда, бривземниеку=дополнения, поворотный=false, то locationContextEnabled=правда, версия=24.0, cssSelectorsEnabled=правда, databaseEnabled=правда, handlesAlerts=правда, browserConnectionEnabled=правда, nativeEvents=false, то webStorageEnabled=правда, applicationCacheEnabled=ложь, takesScreenshot=true}]

может ли кто-нибудь помочь мне с этой проблемой или пролить свет на то, что я могу делать неправильно здесь.

27 101

27 ответов:

У меня была аналогичная проблема, и в конце концов я написал вспомогательную функцию, которая выбирает выпадающие значения.

в конце концов я решил, что мне хорошо выбирать по номеру опции, и поэтому написал метод, который берет элемент и optionNumber и выбирает этот optionNumber. Если optionNumber равен null, он ничего не выбирает (оставляя выпадающий список невыбранным).

var selectDropdownbyNum = function ( element, optionNum ) {
  if (optionNum){
    var options = element.all(by.tagName('option'))   
      .then(function(options){
        options[optionNum].click();
      });
  }
};

Я написал пост в блоге, Если вы хотите более подробно, он также охватывает проверку текст выбранного опция в выпадающем списке: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/

для меня работал как шарм

element(by.cssContainingText('option', 'BeaverBox Testing')).click();

надеюсь, что это помогает.

элегантный подход предполагает создание абстракции аналогично тому, что другие привязки языка selenium предлагают из коробки (например,Select класс в Python или Java).

давайте сделаем удобная обертка и скрыть детали реализации внутри:

var SelectWrapper = function(selector) {
    this.webElement = element(selector);
};
SelectWrapper.prototype.getOptions = function() {
    return this.webElement.all(by.tagName('option'));
};
SelectWrapper.prototype.getSelectedOptions = function() {
    return this.webElement.all(by.css('option[selected="selected"]'));
};
SelectWrapper.prototype.selectByValue = function(value) {
    return this.webElement.all(by.css('option[value="' + value + '"]')).click();
};
SelectWrapper.prototype.selectByPartialText = function(text) {
    return this.webElement.all(by.cssContainingText('option', text)).click();   
};
SelectWrapper.prototype.selectByText = function(text) {
    return this.webElement.all(by.xpath('option[.="' + text + '"]')).click();   
};

module.exports = SelectWrapper;

пример использования (обратите внимание, насколько он читаем и прост в использовании):

var SelectWrapper  = require('select-wrapper');
var mySelect = new SelectWrapper(by.id('locregion'));

# select an option by value
mySelect.selectByValue('4');

# select by visible text
mySelect.selectByText('BoxLox');

решение взято из следующей темы:выбрать -> вариант абстракция.


FYI, создал запрос функции: Select - > Option abstraction.

element(by.model('parent_id')).sendKeys('BKN01');

для доступа к определенному параметру необходимо предоставить селектор nth-child ():

ptor.findElement(protractor.By.css('select option:nth-child(1)')).click();

вот как я сделал свой выбор.

function switchType(typeName) {
     $('.dropdown').element(By.cssContainingText('option', typeName)).click();
};

вот как я это сделал:

$('select').click();
$('select option=["' + optionInputFromFunction + '"]').click();
// This looks useless but it slows down the click event
// long enough to register a change in Angular.
browser.actions().mouseDown().mouseUp().perform();

попробуйте это, это работает для меня:

element(by.model('formModel.client'))
    .all(by.tagName('option'))
    .get(120)
    .click();

вы можете попробовать это надеюсь, что он будет работать

element.all(by.id('locregion')).then(function(selectItem) {
  expect(selectItem[0].getText()).toEqual('Ranjans Mobile Testing')
  selectItem[0].click(); //will click on first item
  selectItem[3].click(); //will click on fourth item
});

другой способ установить элемент option:

var select = element(by.model('organization.parent_id'));
select.$('[value="1"]').click();

мы написали библиотеку, которая включает в себя 3 способа выбора опции:

selectOption(option: ElementFinder |Locator | string, timeout?: number): Promise<void>

selectOptionByIndex(select: ElementFinder | Locator | string, index: number, timeout?: number): Promise<void>

selectOptionByText(select: ElementFinder | Locator | string, text: string, timeout?: number): Promise<void>

дополнительная особенность этой функции заключается в том, что они ждут, пока элемент будет отображаться перед любым действием на это.

вы можете найти его на npm @hetznercloud / транспортир-тест-помощник. Также предоставляются типизации для TypeScript.

может быть, не очень элегантный, но эффективный:

function selectOption(modelSelector, index) {
    for (var i=0; i<index; i++){
        element(by.model(modelSelector)).sendKeys("\uE015");
    }
}

Это просто посылает ключ вниз на выбор, который вы хотите, в нашем случае мы используем modelSelector, но, очевидно, вы можете использовать любой другой селектор.

затем в моей объектной модели страницы:

selectMyOption: function (optionNum) {
       selectOption('myOption', optionNum)
}

и из теста:

myPage.selectMyOption(1);

чтобы выбрать элементы (параметры) с уникальными идентификаторами, как здесь:

<select
    ng-model="foo" 
    ng-options="bar as bar.title for bar in bars track by bar.id">
</select>

Я использую этот:

element(by.css('[value="' + neededBarId+ '"]')).click();

проблема в том, что решения, которые работают на регулярных угловых полях выбора, не работают с угловым материалом md-select и MD-option с использованием транспортира. Этот был опубликован другим, но он работал для меня, и я пока не могу прокомментировать его сообщение (только 23 rep points). Кроме того, я немного очистил его, а не браузер.сон, я использовал браузер.waitForAngular ();

element.all(by.css('md-select')).each(function (eachElement, index) {
    eachElement.click();                    // select the <select>
    browser.waitForAngular();              // wait for the renderings to take effect
    element(by.css('md-option')).click();   // select the first md-option
    browser.waitForAngular();              // wait for the renderings to take effect
});

есть проблема с выбором опций в Firefox, что Droogans взломать исправления, которые я хочу упомянуть здесь явно, надеясь, что это может спасти кого-то от некоторых проблем:https://github.com/angular/protractor/issues/480.

даже если ваши тесты проходят локально с Firefox, вы можете обнаружить, что они терпят неудачу на CircleCI или TravisCI или все, что вы используете для CI&развертывания. Осознание этой проблемы с самого начала спасло бы меня много времени:)

помощник для установки элемента опции:

selectDropDownByText:function(optionValue) {
            element(by.cssContainingText('option', optionValue)).click(); //optionValue: dropDownOption
        }

Если ниже приведен выпадающий список -

            <select ng-model="operator">
            <option value="name">Addition</option>
            <option value="age">Division</option>
            </select>

тогда код транспортира может быть-

        var operators=element(by.model('operator'));
    		operators.$('[value=Addition]').click();

Источник -https://github.com/angular/protractor/issues/600

выберите опцию по индексу:

var selectDropdownElement= element(by.id('select-dropdown'));
selectDropdownElement.all(by.tagName('option'))
      .then(function (options) {
          options[0].click();
      });

мы хотели использовать элегантное решение там, используя материал angularjs, но это не сработало, потому что на самом деле нет тегов option / md-option в DOM, пока не будет нажата кнопка md-select. Таким образом, "элегантный" способ не работал для нас (обратите внимание на угловой материал!) Вот что мы сделали для него вместо этого, не знаю, если его лучший способ, но его определенно работает сейчас

element.all(by.css('md-select')).each(function (eachElement, index) {
    eachElement.click();                    // select the <select>
    browser.driver.sleep(500);              // wait for the renderings to take effect
    element(by.css('md-option')).click();   // select the first md-option
    browser.driver.sleep(500);              // wait for the renderings to take effect
});

нам нужно было выбрать 4 выбора, и пока выбор открыт, есть наложение на пути выбор следующего выбора. вот почему нам нужно подождать 500 мс, чтобы убедиться, что мы не попадаем в беду с материальными эффектами, все еще находящимися в действии.

другой способ установить элемент option:

var setOption = function(optionToSelect) {

    var select = element(by.id('locregion'));
    select.click();
    select.all(by.tagName('option')).filter(function(elem, index) {
        return elem.getText().then(function(text) {
            return text === optionToSelect;
        });
    }).then(function(filteredElements){
        filteredElements[0].click();
    });
};

// using the function
setOption('BeaverBox Testing');
----------
element.all(by.id('locregion')).then(function(Item)
{
 // Item[x] = > // x is [0,1,2,3]element you want to click
  Item[0].click(); //first item

  Item[3].click();     // fourth item
  expect(Item[0].getText()).toEqual('Ranjans Mobile Testing')


});

Я тралил сеть для ответа о том, как выбрать опцию в выпадающем списке модели, и я использовал эту комбинацию, которая помогла мне с угловым материалом.

элемент (by.модель ("ModelName")).щелчок.)(элемент(по.xpath ('xpath location')).нажмите кнопку();

похоже, что при бросании кода все в одной строке он может найти элемент в выпадающем списке.

потребовалось много времени для этого решения я надеюсь, что это поможет кому-то.

вы можете выбрать выпадающие параметры по значению: $('#locregion').$('[value="1"]').click();

Я немного улучшена решение написано Полл. Прежде всего, я исправил код, чтобы быть совместимым с последним API транспортира. И затем я объявляю функцию в разделе "onPrepare" конфигурационного файла транспортира как член обозреватель экземпляр, поэтому на него можно ссылаться из любой спецификации e2e.

  onPrepare: function() {
    browser._selectDropdownbyNum = function (element, optionNum) {
      /* A helper function to select in a dropdown control an option
      * with specified number.
      */
      return element.all(by.tagName('option')).then(
        function(options) {
          options[optionNum].click();
        });
    };
  },

вот как это сделать либо по значению параметра, либо по индексу. Этот пример немного грубый, но он показывает, как делать то, что вы хотите:

html:

<mat-form-field id="your-id">
    <mat-select>
        <mat-option [value]="1">1</mat-option>
        <mat-option [value]="2">2</mat-option>
    </mat-select>
</mat-form-field>

ts:

function selectOptionByOptionValue(selectFormFieldElementId, valueToFind) {

  const formField = element(by.id(selectFormFieldElementId));
  formField.click().then(() => {

    formField.element(by.tagName('mat-select'))
      .getAttribute('aria-owns').then((optionIdsString: string) => {
        const optionIds = optionIdsString.split(' ');    

        for (let optionId of optionIds) {
          const option = element(by.id(optionId));
          option.getText().then((text) => {
            if (text === valueToFind) {
              option.click();
            }
          });
        }
      });
  });
}

function selectOptionByOptionIndex(selectFormFieldElementId, index) {

  const formField = element(by.id(selectFormFieldElementId));
  formField.click().then(() => {

    formField.element(by.tagName('mat-select'))
      .getAttribute('aria-owns').then((optionIdsString: string) => {
        const optionIds = optionIdsString.split(' ');

        const optionId = optionIds[index];
        const option = element(by.id(optionId));
        option.click();
      });
  });
}

selectOptionByOptionValue('your-id', '1'); //selects first option
selectOptionByOptionIndex('your-id', 1); //selects second option

выберите опцию по свойству CSS

element(by.model("organization.parent_id")).element(by.css("[value='1']")).click();

или

element(by.css("#locregion")).element(by.css("[value='1']")).click();

где locregion (id), организация.ид_родительского_объекта(название модели) являются атрибутами выберите элемент.

вы можете выбрать выпадающие параметры следующим образом:

element(by.xpath(//*[@id="locregion"]//option[contains(text(),"Ranjans Mobile Testing")]')).click();