分度器を使用してangular e2eテストのドロップダウンからオプションを選択しようとしています。
選択オプションのコードスニペットは次のとおりです。
<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.version:'10 .9 '、Java.version:' 1.6.0_65 'ドライバー情報:driver.version:不明
私も試しました:
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.Arch:' x86_64 '、os.version:'10 .9'、Java.version: '1.6.0_65'セッションID:bdeb8088-d8ad-0f49-aad9 -82201c45c63fドライバー情報:org.openqa.Selenium.firefox.FirefoxDriver機能[{platform = MAC、acceptSslCerts = true、javascriptEnabled = true、browserName = firefox、rotable = false、locationContextEnabled = true、version = 24.0、cssSelectorsEnabled = true、databaseEnabled = true、handlesAlerts = true、browserConnectionEnabled = true、nativeEvents = false、webStorageEnabled = true、applicationCacheEnabled = false、takesScreenshot = true}]
誰でもこの問題を手伝ってくれたり、ここで間違っている可能性があることに光を当てることができますか?.
同様の問題があり、最終的にドロップダウン値を選択するヘルパー関数を作成しました。
最終的に、オプション番号で選択しても問題ないと判断したため、要素と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言語バインディングがすぐに利用できるものと同様です(例: PythonまたはJavaのSelect
クラス)。
便利なラッパーを作成し、内部に実装の詳細を非表示にします。
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');
次のトピックからの解決策: Select-> option abstraction 。
参考までに、機能リクエストを作成しました: 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
});
オプション要素を設定する別の方法:
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>
この関数の追加機能は、select
に対するアクションが実行される前に要素が表示されるのを待つことです。
Npm @ hetznercloud/protractor-test-helper で見つけることができます。 TypeScriptのタイピングも提供されます。
ここにあるような一意のIDを持つアイテム(オプション)を選択するには:
<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();
問題は、通常のangular selectボックスで機能するソリューションは、Angular Material md-selectおよび分度器を使用したmd-optionでは機能しないということです。これは別の人によって投稿されましたが、私にとってはうまくいきました。私は彼の投稿にまだコメントできません(わずか23 repポイント)。また、browser.sleepの代わりにbrowser.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
});
超エレガントではないかもしれませんが、効率的です:
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);
インデックスでオプションを選択:
var selectDropdownElement= element(by.id('select-dropdown'));
selectDropdownElement.all(by.tagName('option'))
.then(function (options) {
options[0].click();
});
PaulLが作成したソリューションを少し改善しました。まず、最後のProtractor APIと互換性を持つようにコードを修正しました。そして、browserインスタンスのメンバーとして、Protractorの設定ファイルの '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();
});
};
},
オプション要素を設定するヘルパー:
selectDropDownByText:function(optionValue) {
element(by.cssContainingText('option', optionValue)).click(); //optionValue: dropDownOption
}
Firefoxで Droogansのハック を修正するオプションを選択する際に問題があります。これは、誰かがトラブルを軽減できるように、ここで明示的に言及したいものです: https://github.com/angular/protractor/issues/48 。
テストがFirefoxでローカルに合格している場合でも、CircleCIまたはTravisCI、またはCI&deploymentに使用しているものでテストが失敗することがあります。最初からこの問題に気付いていれば、私は多くの時間を節約できたでしょう:)
以下が指定されたドロップダウンである場合-
<select ng-model="operator">
<option value="name">Addition</option>
<option value="age">Division</option>
</select>
次に、protractorjsコードは
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')
});
モデルのドロップダウンでオプションを選択する方法についての答えを求めてネットを探していましたが、Angularマテリアルで役立つこの組み合わせを使用しました。
element(by.model( "ModelName"))。click()。element(By.xpath( 'xpath location'))。click();
コードをすべて1行でスローすると、ドロップダウンで要素を見つけることができるようです。
このソリューションに多くの時間を費やしました。これが誰かの助けになることを願っています。
オプション値またはインデックスのいずれかで行う方法。この例は少し粗雑ですが、あなたが望むことをする方法を示しています:
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
オプション要素を設定する別の方法:
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');
値でドロップダウンオプションを選択できます:$('#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();
}
}
}
})
}
Anglejsマテリアルを使用してエレガントなソリューションを使用したかったのですが、md-selectがクリックされるまでDOMに実際にはoption/md-optionタグがないため、うまくいきませんでした。そのため、「エレガントな」方法は機能しませんでした(angularに注意してください!)代わりにこれを使用しました。
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ミリ秒待機する必要があります。