如何选择选项在下拉式量程器 e2e 测试

我试图选择一个选项从下拉式角度 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-1215: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-1215:42:01’ System info: 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 能力[{ Platform = MAC,eptsslCerts = true,javascriptEnable = true,BrowserName = firefox,rottable = false,locationContextEnable = true,version = 24.0,cssSelectorsEnable = true,database aseEnable = true,handlesAlerts = true,BrowserConnectionEnable = true,natveEvents = false,webStorageEnable = true,applicationCacheEnable = false,takesScreenshot = true }]

有没有人能帮我解决这个问题或者告诉我哪里做错了。

171602 次浏览

要访问特定的选项,需要提供 nth-child ()选择器:

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

I had a similar problem, and eventually wrote a helper function that selects dropdown values.

I eventually decided that I was fine selecting by option number, and therefore wrote a method that takes an element and the optionNumber, and selects that optionNumber. If the optionNumber is null it selects nothing (leaving the dropdown unselected).

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/

You can try this hope it will work

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

也许不是特别优雅,但效率很高:

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

这只是在您想要的选择上向下发送键,在我们的示例中,我们使用的是 model Selector,但显然您可以使用任何其他选择器。

然后在我的页面对象模型中:

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

从测试结果来看:

myPage.selectMyOption(1);

我是这么做的:

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

我就是这样挑选的。

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

For me worked like a charm

element(by.cssContainingText('option', 'BeaverBox Testing')).click();
element(by.model('parent_id')).sendKeys('BKN01');

我们希望使用 angularjs 的材料来使用这个优雅的解决方案,但是它不起作用,因为在单击 md-select 之前,DOM 中实际上没有 option/md-option 标记。因此,“优雅”的方式不适合我们(注意角材料!)下面是我们为它所做的,不知道是否是最好的方式,但它现在肯定工作

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

We needed to have 4 selects selected and while the select is open, there is an overlay in the way of selecting the next select. thats why we need to wait 500ms to make sure we don't get into trouble with the material effects still being in action.

一种优雅的方法 将涉及 做一个抽象的概念,类似于其他硒语言绑定提供的开箱即用的绑定(例如 Python 或 Java 中的 Select类)。

让我们创建一个 convenient wrapper并在其中隐藏实现细节:

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

解决方案来自以下主题: 选择-> 选项抽象


仅供参考,创建了一个特性请求: 选择-> 选项抽象

试试这个,对我很有效:

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

To select items (options) with unique ids like in here:

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

Another way to set an option element:

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

在 Firefox 中选择 Droogans's hack修复的选项有一个问题,我想在这里明确提到,希望它可以为某些人节省一些麻烦: https://github.com/angular/protractor/issues/480

即使您的测试在 Firefox 本地通过,您也可能会发现它们在 CircleCI 或 TravisCI 或其他用于 CI 和部署的测试中失败。从一开始就意识到这个问题可以节省我很多时间:)

问题是,解决方案,工作在规则的角度选择框不工作的角度材料 md 选择和 md 选项使用量角器。这是另外一个人发的帖子,但是对我很有效,我还不能对他的帖子进行评论(只有23个代表点)。另外,我稍微清理了一下,没有使用 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
});
----------
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')




});

我一直在网上搜寻如何在模型下拉菜单中选择一个选项的答案,我已经使用了这个组合,它帮助我摆脱了角度材料。

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

看起来,当把所有代码放在一行中时,它可以在下拉列表中找到元素。

这个解决方案花了很多时间,我希望这能帮到某人。

设置选项元素的另一种方法:

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

您可以根据值选择下拉选项: $('#locregion').$('[value="1"]').click();

设置 an 选项元素的助手:

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>

那么 protractorjs 代码可以是-

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

我对 PaulL 写的解法做了一点改进。 首先,我修改了代码,使其与上一个量角器 API 兼容。然后,我在 Protracer 配置文件的‘ onReady’部分中将函数声明为 浏览器实例的成员,这样就可以从任何 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();
});
};
},

通过 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)、 Organization ation.rent _ id (model name)是 select 元素的属性。

您可以像下面这样选择下拉选项:

element(by.xpath(
'//*[@id="locregion"]//option[contains(text(),"Ranjans Mobile Testing")]'
)).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/量角器-测试助手上找到它。 还提供了 TypeScript 的类型。

Here is how to do it by either option value or index. This example is a bit crude, but it shows how to do what you want:

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>

总结:

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


})


}

我们可以为此创建一个自定义 DropDown 类并添加一个方法,如下所示:

async selectSingleValue(value: string) {
await this.element.element(by.xpath('.//option[normalize-space(.)=\'' + value + '\']')).click();
}

另外,为了验证当前选择的值,我们可以:

async getSelectedValues() {
return await this.element.$('option:checked').getText();
}

下面的例子是最简单的方法。我已经测试并通过了量角器版本 5.4.2

//Drop down selection  using option's visibility text


element(by.model('currency')).element(by.css("[value='Dollar']")).click();
Or use this, it   $ isshort form for  .By.css
element(by.model('currency')).$('[value="Dollar"]').click();

//To select using index


var select = element(by.id('userSelect'));
select.$('[value="1"]').click(); // To select using the index .$ means a shortcut to .By.css

全密码

describe('Protractor Demo App', function() {


it('should have a title', function() {


browser.driver.get('http://www.way2automation.com/angularjs-protractor/banking/#/');
expect(browser.getTitle()).toEqual('Protractor practice website - Banking App');
element(by.buttonText('Bank Manager Login')).click();
element(by.buttonText('Open Account')).click();


//Drop down selection  using option's visibility text
element(by.model('currency')).element(by.css("[value='Dollar']")).click();


//This is a short form. $ in short form for  .By.css
// element(by.model('currency')).$('[value="Dollar"]').click();


//To select using index
var select = element(by.id('userSelect'));
select.$('[value="1"]').click(); // To select using the index .$ means a shortcut to .By.css
element(by.buttonText("Process")).click();
browser.sleep(7500);// wait in miliseconds
browser.switchTo().alert().accept();


});
});

这是一个简单的单行答案,其中角度有专门的定位器,可以帮助选择和索引从列表。

element.all(by.options('o.id as o.name for o in organizations')).get(Index).click()

如果上面的答案都不适合你,试试这个

也可用于异步/等待

用于按文本选择选项

let textOption = "option2"
await element(by.whichever('YOUR_DROPDOWN_SELECTOR'))
.getWebElement()
.findElement(by.xpath(`.//option[text()="${textOption}"]`))
.click();

或者数字

let optionNumber = 2
await element(by.whichever('YOUR_DROPDOWN_SELECTOR'))
.getWebElement()
.findElement(by.xpath(`.//option[${optionNumber}]`))
.click();

当然,您可能需要修改子选项的 xpath

不要问我为什么,但这是唯一的方法,我可以自动下拉,当我已经失去了希望


更新

实际上,有一种情况下,即使这种方法也不起作用。周围的工作是有点丑陋,但工作。我只需要选择值 两次

这对 角状物质来说很管用

element(by.css("mat-select[formcontrolname=myMatSelect]")).sendKeys(valueToSet);

如果选项中没有“ valueToSet”,则不应该设置它。

使用我找到的索引选择选项的最简单方法是,

var selectDropdownElement = await element(by.xpath("Some Xpath"));
await selectDropdownElement.all(by.tagName('option')).then(function (options) {
options[index].click();
});

'index' is the option number which you want to click