Select -> option abstraction

2019-01-02 21:04发布

In Python, Java and several other selenium bindings, there is a very convenient abstraction over select->option HTML constructions, a Select class.

For example, imagine there is the following select tag:

<select id="fruits" class="select" name="fruits">
    <option value="1">Banana</option>
    <option value="2">Mango</option>
</select>

Here is how we can operate it in Python:

from selenium.webdriver.support.ui import Select

select = Select(driver.find_element_by_id('fruits'))

# get all options
print select.options

# get all selected options
print select.all_selected_options

# select an option by value
select.select_by_value('1')

# select by visible text
select.select_by_visible_text('Mango')

In other words, it is a very transparent and easy to use abstraction.

Is is possible to manipulate select tag in protractor in a similar manner?


This is not a duplicate of How to select option in drop down protractorjs e2e tests or How to click on option in select box in Protractor test?.

4条回答
柔情千种
2楼-- · 2019-01-02 21:40

No need to implement it on you own :). We wrote a library which includes 3 ways to select an 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>

Additional feature of this functions is that they wait for the element to be displayed before any action on the select is performed.

You can find it on npm @hetznercloud/protractor-test-helper. Typings for TypeScript are provided.

查看更多
几人难应
3楼-- · 2019-01-02 21:47

Starting Protractor v.0.22.0 you can just use the new By.cssContainingText locator:

element(by.cssContainingText('option', 'Mango'));

See the API reference.

查看更多
孤独总比滥情好
4楼-- · 2019-01-02 21:54

Code with Typescript:

Tagname:

by.tagName('option')

by.tagName('md-option')

by.tagName('li')

selectOption(selector: string, item: string) {
    let selectList: any;
    let desiredOption: any;

    selectList = element(by.css(selector));
    selectList.click();

    selectList.findElements(by.tagName('option'))
        .then(function findMatchingOption(options: any) {
            options.some(function (option: any) {
                option.getText().then(function doesOptionMatch(text: string) {
                    if (item === text) {
                        desiredOption = option;
                        return true;
                    }
                });
            });
        })
        .then(function clickOption() {
            if (desiredOption) {
                desiredOption.click();
            }
        });
}

Used:

selectOption('//select[@id="food"]', 'Pizza');
查看更多
余生请多指教
5楼-- · 2019-01-02 22:01

No such thing in Protractor, but we can write our own:

select-wrapper.js

'use strict';

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;


Usage

var SelectWrapper  = require('select-wrapper');
var mySelect = new SelectWrapper(by.id('fruits'));

# select an option by value
mySelect.selectByValue('1');

# select by visible text
mySelect.selectByText('Mango');


Note that Select is a reserved word in JavaScript

查看更多
登录 后发表回答