Comment sélectionner l'option dans les tests drop down protractorjs e2e
j'essaie de sélectionner une option à partir d'une goutte pour les tests E2E angulaires en utilisant protractor.
Voici l'extrait de code de l'option 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>
j'ai essayé:
ptor.findElement(protractor.By.css('select option:1')).click();
cela me donne l'erreur suivante:
une chaîne invalide ou illégale a été spécifiée Build info: version: '2.35.0', révision: 'c916b9d', heure: '2013-08-12 15: 42: 01" Informations système: os.nom: "Mac OS X", os.arc: 'x86_64', os.version: '10.9", de java.version: "1.6.0_65" Des informations sur les pilotes: pilote.version: inconnue
j'ai aussi essayé:
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();
cela me donne l'erreur suivante:
ElementNotVisibleError: l'Élément n'est pas visible et ne peuvent donc pas être en interaction avec Commande duration ou timeout: 9 millisecondes Construire info: version: '2.35.0', révision: 'c916b9d', heure: '2013-08-12 15: 42: 01' Informations système: os.nom: "Mac OS X", os.arc: 'x86_64', os.version: '10.9", de java.version: "1.6.0_65" Nom de Session: bdeb8088-d8ad-0f49-aad9-82201c45c63f Informations sur le conducteur: org.openqa.nium.Firefox.FirefoxDriver Capacités [{platform=MAC, acceptSslCerts= true, javascriptEnabled = true, browserName = firefox, rotatable=false, locationtextenabled=true, version = 24.0, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot = true}]
quelqu'un Peut-il m'aider avec ce problème ou de jeter un peu de lumière sur ce que je fais de mal ici.
27 réponses
j'ai eu un problème similaire, et j'ai finalement écrit une fonction d'aide qui sélectionne les valeurs de descente.
j'ai finalement décidé que j'allais bien choisir par numéro d'option, et j'ai donc écrit une méthode qui prend un élément et l'optionNumber, et sélectionne cet optionNumber. Si optionNumber est nul, il ne sélectionne rien (laissant la liste déroulante non sélectionnée).
var selectDropdownbyNum = function ( element, optionNum ) {
if (optionNum){
var options = element.all(by.tagName('option'))
.then(function(options){
options[optionNum].click();
});
}
};
j'ai écrit un billet de blog si vous voulez plus de détails, il couvre également vérifier le texte de l'option sélectionnée dans une liste déroulante: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation /
Pour moi a fonctionné comme un charme
element(by.cssContainingText('option', 'BeaverBox Testing')).click();
J'espère que ça aidera.
une approche élégante impliquerait faire une abstraction similaire à ce que d'autres fixations de langage sélénium offrent hors de la boîte (par exemple Select
classe en Python ou en Java).
faisons un convenient wrapper et cacher les détails de la mise en œuvre à l'intérieur:
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;
exemple d'utilisation (notez à quel point il est lisible et facile à utiliser):
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');
Solution tirée du thème suivant: sélectionner -> option abstraction .
FYI, a créé une requête de caractéristique: sélectionner -> abstraction d'option .
pour accéder à une option spécifique, vous devez fournir le sélecteur nth-child ():
ptor.findElement(protractor.By.css('select option:nth-child(1)')).click();
C'est comme ça que j'ai fait ma sélection.
function switchType(typeName) {
$('.dropdown').element(By.cssContainingText('option', typeName)).click();
};
Voici comment je l'ai fait:
$('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();
Essayer, c'est de travailler pour moi:
element(by.model('formModel.client'))
.all(by.tagName('option'))
.get(120)
.click();
Vous pouvez essayer ce espère que cela va fonctionner
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
});
une autre façon de définir un élément d'option:
var select = element(by.model('organization.parent_id'));
select.$('[value="1"]').click();
nous avons écrit une bibliothèque qui comprend 3 façons de choisir une option:
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>
caractéristique Supplémentaire de ce qu'ils attendent de l'élément à afficher avant toute action sur le select
est effectuée.
Vous pouvez le trouver sur npm @hetznercloud/rapporteur-test-helper . Typings pour les caractères d'imprimerie sont fournis.
peut-être pas très élégant, mais efficace:
function selectOption(modelSelector, index) {
for (var i=0; i<index; i++){
element(by.model(modelSelector)).sendKeys("\uE015");
}
}
cela envoie juste la clé vers le bas sur le select que vous voulez, dans notre cas, nous utilisons modelSelector mais évidemment vous pouvez utiliser n'importe quel autre selector.
puis dans mon modèle d'objet de page:
selectMyOption: function (optionNum) {
selectOption('myOption', optionNum)
}
et du test:
myPage.selectMyOption(1);
pour sélectionner des éléments (options) avec des identifiants uniques comme ici:
<select
ng-model="foo"
ng-options="bar as bar.title for bar in bars track by bar.id">
</select>
j'utilise ceci:
element(by.css('[value="' + neededBarId+ '"]')).click();
le problème est que les solutions qui fonctionnent sur les boîtes régulières de sélection angulaire ne fonctionnent pas avec le matériau angulaire md-select et md-option en utilisant protractor. Celui-ci a été posté par un autre, mais il a fonctionné pour moi et je ne suis pas encore en mesure de commenter sur son poste (seulement 23 points rep). Aussi, j'ai nettoyé un peu, au lieu de navigateur.le sommeil, j'ai utilisé le navigateur.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
});
il y a un problème avec la sélection d'options dans Firefox que Correction de hack de Droogans que je veux mentionner ici explicitement, en espérant qu'il pourrait sauver quelqu'un certains problème: https://github.com/angular/protractor/issues/480 .
même si vos tests sont réussis localement avec Firefox, vous pourriez trouver qu'ils ne fonctionnent pas sur CircleCI ou TravisCI ou quoi que vous utilisiez pour CI&deployment. En étant conscient de ce problème à partir de la début m'aurait sauvé beaucoup de temps:)
Aide pour définir l'option de l'élément:
selectDropDownByText:function(optionValue) {
element(by.cssContainingText('option', optionValue)).click(); //optionValue: dropDownOption
}
Si ci-dessous est la baisse indiquée -
<select ng-model="operator">
<option value="name">Addition</option>
<option value="age">Division</option>
</select>
puis protractorjs code peut être -
var operators=element(by.model('operator'));
operators.$('[value=Addition]').click();
sélectionner L'option par Index:
var selectDropdownElement= element(by.id('select-dropdown'));
selectDropdownElement.all(by.tagName('option'))
.then(function (options) {
options[0].click();
});
nous voulions utiliser la solution élégante là-haut en utilisant le matériau angularjs mais cela n'a pas fonctionné car il n'y a en fait aucune option / md-option dans le DOM tant que le md-select n'a pas été cliqué. Ainsi ,la méthode" élégante " n'a pas fonctionné pour nous (notez le matériau angulaire!) Voici ce que nous avons fait pour elle à la place, ne sais pas si c'est la meilleure façon, mais son fonctionnement défini maintenant
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
});
nous avions besoin d'avoir 4 sélections sélectionnées et pendant que le select est ouvert, il y a une superposition dans la manière de sélectionner le prochain select. c'est pourquoi nous devons attendre 500m pour nous assurer de ne pas avoir de problèmes avec les effets matériels toujours en action.
une autre façon de définir un élément d'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')
});
j'ai été à la recherche du filet pour une réponse sur la façon de choisir une option dans un dropdown modèle et j'ai utilisé cette combinaison qui m'a aidé avec le matériel angulaire.
élément(par.modèle("ModelName")).cliquer.)(élément(Par.xpath('emplacement xpath')).cliquez sur();
il semble qu'en lançant le code tout en une seule ligne, il pourrait trouver l'élément dans la liste déroulante.
a pris beaucoup de temps pour cette solution j'espère que ce aide à quelqu'un.
vous pouvez sélectionner les options dropdown par valeur:
$('#locregion').$('[value="1"]').click();
j'ai amélioré un peu la solution écrite par PaulL. Tout d'abord, j'ai corrigé le code pour qu'il soit compatible avec la dernière API Protractor. Et puis je déclare la fonction dans la section 'onPrepare' d'un fichier de configuration de Protractor en tant que membre de l'instance browser , de sorte qu'elle peut être référencée sous n'importe quelle spécification 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();
});
};
},
Voici comment le faire par la valeur de l'option ou l'index . Cet exemple est un peu brut, mais il montre comment faire ce que vous voulez:
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
sélectionner l'option correspondant à la propriété CSS
element(by.model("organization.parent_id")).element(by.css("[value='1']")).click();
ou
element(by.css("#locregion")).element(by.css("[value='1']")).click();
Où locregion(id), de l'organisation.parent_id(nom du modèle) sont les attributs de l'élément select.
vous pouvez sélectionner les options de réduction comme ceci:
element(by.xpath(//*[@id="locregion"]//option[contains(text(),"Ranjans Mobile Testing")]')).click();