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.
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/
Für mich arbeitete wie ein Zauber
element(by.cssContainingText('option', 'BeaverBox Testing')).click();
Ich hoffe es hilft.
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 .
element(by.model('parent_id')).sendKeys('BKN01');
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();
So habe ich meine Auswahl getroffen.
function switchType(typeName) {
$('.dropdown').element(By.cssContainingText('option', typeName)).click();
};
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();
Probieren Sie es aus, es funktioniert für mich:
element(by.model('formModel.client'))
.all(by.tagName('option'))
.get(120)
.click();
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
});
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.
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();
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
});
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);
Option nach Index auswählen:
var selectDropdownElement= element(by.id('select-dropdown'));
selectDropdownElement.all(by.tagName('option'))
.then(function (options) {
options[0].click();
});
Helfer beim Festlegen eines Optionselements:
selectDropDownByText:function(optionValue) {
element(by.cssContainingText('option', optionValue)).click(); //optionValue: dropDownOption
}
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 :)
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();
----------
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')
});
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();
});
};
},
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.
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
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');
Sie können Dropdown-Optionen nach dem Wert auswählen: $('#locregion').$('[value="1"]').click();
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();
}
}
}
})
}
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.