it-swarm.com.de

Auswahl der Option in Dropdown-Winkelmesser-E2e-Tests

Ich versuche eine Option aus einem Dropdown für die e2e-Winkeltests mit Winkelmesser auszuwählen.

Hier ist der Code-Ausschnitt der select-Option:

<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>

Ich habe versucht:

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

Dies gibt mir den folgenden Fehler:

Es wurde eine ungültige oder unzulässige Zeichenfolge angegebenBuildinfo: Version: '2.35.0', Revision: 'c916b9d', Uhrzeit: '2013-08-12 15:42:01' Systeminfo: os.name : 'Mac OS X', os.Arch: 'x86_64', os.version: '10 .9 ', Java.version:' 1.6.0_65 ' Treiberinfo: Treiberversion: unbekannt

Ich habe auch versucht:

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();

Dies gibt mir den folgenden Fehler:

ElementNotVisibleError: Das Element ist zurzeit nicht sichtbar und kann daher nicht mit .__ interagiert werden. Befehlsdauer oder Timeout: 9 Millisekunden Build-Info: Version: '2.35.0', Revision: 'c916b9d', Uhrzeit: '2013-08-12 15:42:01' Systeminfo: os.name: 'Mac OS X', os.Arch: 'x86_64', os.version: '10 .9 ', Java.version:' 1.6.0_65 ' Sitzungs-ID: bdeb8088-d8ad-0f49-aad9-82201c45c63f Treiberinfo: org.openqa.Selenium.firefox.FirefoxDriver Capabilities [{Plattform = MAC, acceptSslCerts = true, javascriptEnabled = true, browserName = firefox, rotatable = false, locationContextEnabled = true, version = 24.0, cssSelectorsEnabled = true, databaseEnabled = true, handleAlerts = true, browserConnectionEnabled = false , webStorageEnabled = true, applicationCacheEnabled = false, takesScreenshot = true}]

Kann mir bitte jemand bei diesem Problem helfen oder ein wenig Licht darauf werfen, was ich hier falsch mache.

107
Ranjan Bhambroo

Ich hatte ein ähnliches Problem und schrieb schließlich eine Hilfsfunktion, die Dropdown-Werte auswählt.

Ich entschied schließlich, dass es mir gut ging, nach Optionsnummer zu selektieren, und schrieb deshalb eine Methode, die ein Element und die optionNumber übernimmt und diese OptionNumber auswählt. Wenn die OptionNumber null ist, wird nichts ausgewählt (die Dropdown-Liste bleibt deaktiviert).

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

Ich habe einen Blog-Post geschrieben, wenn Sie mehr Details wünschen. In diesem Dropdown-Menü wird auch der Text der ausgewählten Option überprüft: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/

76
PaulL

Für mich arbeitete wie ein Zauber

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

Ich hoffe es hilft.

236
Fatz

Ein eleganter Ansatz würde eine Abstraktion erzeugen ähnlich wie bei anderen Selenium-Sprachbindungen "out of the box" (z. B. Select-Klasse in Python oder Java) bieten.

Lassen Sie uns ein praktischer Wrapper erstellen und die Implementierungsdetails darin ausblenden:

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;

Anwendungsbeispiel (Beachten Sie, wie lesbar und benutzerfreundlich es ist):

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');

Lösung aus dem folgenden Thema: Wählen Sie -> Option Abstraktion .


Zu Ihrer Information, eine Feature-Anfrage erstellt: Wählen Sie -> Option Abstraktion .

26
alecxe
element(by.model('parent_id')).sendKeys('BKN01');
20
Sandesh Danwale

Um auf eine bestimmte Option zuzugreifen, müssen Sie den Selektor nth-child () angeben:

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

So habe ich meine Auswahl getroffen.

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

So habe ich es gemacht:

$('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();
5
Droogans

Probieren Sie es aus, es funktioniert für mich:

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

Sie können diese Hoffnung versuchen, dass es funktioniert

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
});
4
Zahid Afaque

Eine andere Möglichkeit, ein Optionselement festzulegen:

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

Wir haben eine Bibliothek geschrieben, die drei Möglichkeiten enthält, eine Option auszuwählen:

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>

Eine weitere Funktion dieser Funktionen ist, dass sie darauf warten, dass das Element angezeigt wird, bevor eine Aktion für die Variable select ausgeführt wird.

Sie finden es unter npm @ hetznercloud/protractor-test-helper . Typisierungen für TypeScript werden ebenfalls bereitgestellt.

3
crashbus

So wählen Sie Elemente (Optionen) mit eindeutigen IDs wie hier aus:

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

Ich benutze das:

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

Das Problem ist, dass Lösungen, die mit regulären Winkelauswahlfeldern arbeiten, nicht mit m-select und md-Option von Angular Material mit Winkelmesser funktionieren. Dieses wurde von einem anderen gepostet, aber es hat für mich funktioniert und ich kann noch nicht zu seinem Beitrag kommentieren (nur 23 Wiederholungspunkte). Außerdem habe ich es etwas aufgeräumt, statt browser.sleep habe ich browser.waitForAngular () verwendet.

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
});
2
peterhendrick

Vielleicht nicht besonders elegant, aber effizient:

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

Dadurch wird nur die Taste nach unten gedrückt, die Sie auswählen möchten. In unserem Fall verwenden wir modelSelector. Natürlich können Sie auch einen anderen Selector verwenden.

Dann in meinem Seitenobjektmodell:

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

Und aus dem Test:

myPage.selectMyOption(1);
2
Calahad

Option nach Index auswählen:

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

Helfer beim Festlegen eines Optionselements:

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

Es gibt ein Problem bei der Auswahl von Optionen in Firefox, dass Droogans 'Hack Fixes, die ich hier explizit erwähnen möchte, in der Hoffnung, dass dies jemandem Ärger erspart: https://github.com/angular/protractor/issues/480 .

Selbst wenn Ihre Tests lokal mit Firefox bestanden werden, stellen Sie möglicherweise fest, dass sie bei CircleCI oder TravisCI oder was auch immer Sie für CI & Bereitstellung verwenden, fehlschlagen. Dieses Problem von Anfang an zu kennen, hätte mir viel Zeit gespart :)

1
Julia Jacobs

Wenn unten die angegebene Dropdown-

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

Dann kann der protractorjs-Code

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

Quelle - https://github.com/angular/protractor/issues/600

1
Ajay Patil
----------
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')


});
0
Pramod Dutta

Ich habe die von PaulL geschriebene Lösung etwas verbessert. Zuerst habe ich den Code so korrigiert, dass er mit der letzten Protractor-API kompatibel ist. Und dann erkläre ich die Funktion im 'onPrepare'-Abschnitt einer Protractor-Konfigurationsdatei als Mitglied der browser -Instanz, sodass sie von jeder e2e-Spezifikation aus referenziert werden kann.

  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();
        });
    };
  },
0
trunikov

Ich habe im Netz nach einer Antwort gesucht, wie man eine Option in einem Dropdown-Modell auswählt, und ich habe diese Kombination verwendet, die mir beim Angular-Material geholfen hat.

element (by.model ("ModelName")). click (). element (By.xpath ('xpath-Speicherort')). click ();

es scheint, als könnte der Code das Element in der Dropdown-Liste finden.

Ich habe viel Zeit für diese Lösung gebraucht. Ich hoffe, das hilft jemandem.

0
tony2tones

So tun Sie es entweder mit dem Optionswert oder dem Index . Dieses Beispiel ist etwas grob, aber es zeigt, wie man das macht, was man will:

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
0
KVarmark

Eine andere Möglichkeit, ein Optionselement festzulegen:

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');
0
flaviomeira10

Sie können Dropdown-Optionen nach dem Wert auswählen: $('#locregion').$('[value="1"]').click();

0
Sander Lepik
static selectDropdownValue(dropDownLocator,dropDownListLocator,dropDownValue){
    let ListVal ='';
    WebLibraryUtils.getElement('xpath',dropDownLocator).click()
      WebLibraryUtils.getElements('xpath',dropDownListLocator).then(function(selectItem){
        if(selectItem.length>0)
        {
            for( let i =0;i<=selectItem.length;i++)
               {
                   if(selectItem[i]==dropDownValue)
                   {
                       console.log(selectItem[i])
                       selectItem[i].click();
                   }
               }            
        }

    })

}
0
Javed Ali

Wir wollten die elegante Lösung dort oben mit eckjs-Material verwenden, aber es funktionierte nicht, da im DOM tatsächlich keine Option/md-Option-Tags enthalten sind, bis der Befehl md-select angeklickt wurde. Der "elegante" Weg hat also für uns nicht funktioniert (beachten Sie das eckige Material!) Hier haben wir stattdessen getan, wissen Sie nicht, ob es der beste Weg ist, aber es funktioniert jetzt definitiv

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

Wir mussten 4 Auswahlen auswählen, und während die Auswahl geöffnet ist, wird die Auswahl der nächsten Auswahl überlagert. Deshalb müssen wir 500 ms warten, um sicherzustellen, dass wir nicht mit den Materialeffekten in Konflikt geraten. 

0
pascalwhoop