Cách chọn tùy chọn trong các bài kiểm tra thước đo góc thả xuống


121

Tôi đang cố gắng chọn một tùy chọn từ menu thả xuống cho các bài kiểm tra góc e2e bằng thước đo góc.

Đây là đoạn mã của tùy chọn đã chọn:

<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>

Tôi đã thử:

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

Điều này mang lại cho tôi lỗi sau:

Một chuỗi không hợp lệ hoặc bất hợp pháp đã được chỉ định Thông tin bản dựng: phiên bản: '2.35.0', bản sửa đổi: 'c916b9d', thời gian: '2013-08-12 15:42:01' Thông tin hệ thống: os.name: 'Mac OS X' , os.arch: 'x86_64', os.version: '10 .9 ', java.version:' 1.6.0_65 'Thông tin trình điều khiển: driver.version: không xác định

Tôi cũng đã thử:

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

Điều này mang lại cho tôi lỗi sau:

ElementNotVibleError: Phần tử hiện không hiển thị và do đó có thể không được tương tác với Thời lượng lệnh hoặc thời gian chờ: 9 mili giây Thông tin bản dựng: phiên bản: '2.35.0', bản sửa đổi: 'c916b9d', thời gian: '2013-08-12 15:42: 01 'Thông tin hệ thống: os.name:' Mac OS X ', os.arch:' x86_64 ', os.version: '10 .9', java.version: '1.6.0_65' Session ID: bdeb8088-d8ad-0f49-aad9 -82201c45c63f Thông tin trình điều khiển: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform = MAC, acceptSslCerts = true, javascriptEnabled = true, browserName = firefox, rotatable = false, locationContextEnabled = true, version = 24.0, cssSelectorsEnabled = true, databaseEnabled = true, handleAlerts = true, browserConnectionEnabled = true, nativeEvents = false, webStorageEnabled = true, applicationCacheEnabled = false, takeScreenshot = true}]

Bất cứ ai có thể vui lòng giúp tôi với vấn đề này hoặc ném một số ánh sáng vào những gì tôi có thể đang làm sai ở đây.

Câu trả lời:


88

Tôi đã gặp sự cố tương tự và cuối cùng đã viết một hàm trợ giúp chọn giá trị thả xuống.

Cuối cùng, tôi quyết định rằng tôi đã ổn khi chọn theo số tùy chọn, và do đó đã viết một phương thức lấy một phần tử và optionNumber, và chọn optionNumber đó. Nếu optionNumber là null, nó sẽ không chọn gì (bỏ chọn menu thả xuống).

var selectDropdownbyNum = function ( element, optionNum ) {
  if (optionNum){
    var options = element.all(by.tagName('option'))   
      .then(function(options){
        options[optionNum].click();
      });
  }
};

Tôi đã viết một bài đăng trên blog nếu bạn muốn biết thêm chi tiết, nó cũng bao gồm việc xác minh văn bản của tùy chọn đã chọn trong trình đơn thả xuống: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/


1
Không hoạt động với tôi, got element.findElements không phải là một hàm.
Justin

251

Đối với tôi làm việc như một cái duyên

element(by.cssContainingText('option', 'BeaverBox Testing')).click();

Hy vọng nó giúp.


2
Tiểu lưu ý - v0.22 chỉ (Tôi chỉ cần đi để thay thế mã của tôi với ngày hôm nay, và đã phải nâng cấp để có được nó)
PaulL

Có cách nào để nhắm mục tiêu các yếu tố bằng cách sử dụng điều này không? Chẳng hạn như có các menu chọn State trùng lặp.
Christopher Marshall,

11
Christopher, ElementFinderlà người có khả năng thực hiện chuỗi, vì vậy bạn có thể làm:element(by.css('.specific-select')).element(by.cssContainingText('option', 'BeaverBox Testing')).click();
Joel Kornbluh, 29/09

6
Lưu ý rằng bạn có thể nhận được các kết quả phù hợp từng phần, vì vậy 'Xỉu' sẽ khớp với 'Xỉu'.
TrueWill

3
Để thêm vào nhận xét của TrueWill: Mặt trái của giải pháp này là nếu bạn có hai tùy chọn giống nhau, nó sẽ sử dụng tùy chọn được tìm thấy cuối cùng - tùy chọn tạo ra lỗi dựa trên lựa chọn sai. Điều làm việc cho tôi là stackoverflow.com/a/25333326/1945990
Mike W

29

Một cách tiếp cận thanh lịch sẽ liên quan đến việc tạo ra một sự trừu tượng tương tự như những gì mà các ràng buộc ngôn ngữ selen khác cung cấp ngay lập tức (ví dụ:Select lớp trong Python hoặc Java).

Hãy tạo một trình bao bọc thuận tiện và ẩn các chi tiết triển khai bên trong:

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;

Ví dụ về cách sử dụng (lưu ý cách dễ đọc và dễ sử dụng):

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

Giải pháp lấy từ chủ đề sau: Chọn -> trừu tượng hóa tùy chọn .


FYI, đã tạo một yêu cầu tính năng: Chọn -> trừu tượng hóa tùy chọn .


Tại sao bạn sử dụng 'return' trong các công cụ được chọn? Điều đó có cần thiết không?
Michiel

1
@Michiel điểm tốt. Có thể cần thiết nếu bạn muốn giải quyết rõ ràng lời hứa được trả lại bởi click(). Cảm ơn.
alecxe

20
element(by.model('parent_id')).sendKeys('BKN01');

1
Nó là chính xác nhất đối với tôi. Với cssContainingText, bạn không chắc chắn nắm bắt được trường mong muốn. Chỉ cần suy nghĩ nếu bạn có 2 hộp chọn có cùng giá trị. +1
YoBre

4
Xin lỗi, BKN01 là gì?
Gerfried

1
@Gerfried BKN01 là văn bản bạn muốn chọn từ trình đơn thả xuống.
MilanYadav

@GalBracha Xin lỗi đã không hiểu được bạn
MilanYadav 10/10/16

Nếu bạn có một tùy chọn khác có cùng ưu điểm với BKN01, nó sẽ không hoạt động. Một ngẫu nhiên sẽ được chọn.
zs2020

15

Để truy cập một tùy chọn cụ thể, bạn cần cung cấp bộ chọn thứ n-con ():

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

Điều này không cung cấp câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ tác giả, hãy để lại bình luận bên dưới bài đăng của họ.
jpw

@jpw là câu trả lời của tôi sai. hay nó chỉ đơn giản là công thức của câu trả lời của tôi sai?
bekite

Công thức của một câu trả lời như một câu hỏi là tại sao. Tôi không biết đó có phải là câu trả lời chính xác hay không. Nếu đúng, bạn nên xây dựng nó như vậy.
jpw

3
@bekite không làm việc cho me.Still nhận được lỗi phần tử lỗi Không nhìn thấy được khi tôi đã cố gắng gợi ý của bạn
Ranjan Bhambroo

8

Đây là cách tôi đã lựa chọn của mình.

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

5

Đây là cách tôi đã làm điều đó:

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

Để đợi cho góc kết thúc quá trình xử lý đang chờ xử lý, hãy sử dụng waitForAngular()phương pháp của thước đo góc .
Avi Cherry

5

Hãy thử điều này, nó đang làm việc cho tôi:

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

4

Bạn có thể thử điều này hy vọng nó sẽ hoạt động

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

4

Một cách khác để đặt một phần tử tùy chọn:

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

var orderTest = element (by.model ('ctrl.supplier.orderTest')) orderTest. $ ('[value = "1"]'). click (); đang gặp lỗi Bởi (công cụ chọn css, [value = "3"])
Anuj KC

3

Để chọn các mục (tùy chọn) với các id duy nhất như trong đây:

<select
    ng-model="foo" 
    ng-options="bar as bar.title for bar in bars track by bar.id">
</select>

Tôi đang sử dụng cái này:

element(by.css('[value="' + neededBarId+ '"]')).click();

3

Chúng tôi đã viết một thư viện bao gồm 3 cách để chọn một tùy chọn:

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>

Tính năng bổ sung của các chức năng này là chúng đợi phần tử được hiển thị trước khi có bất kỳ hành động nào trên select .

Bạn có thể tìm thấy nó trên npm @ hetznercloud / protractor-test-helper . Các kiểu chữ cho TypeScript cũng được cung cấp.


2

Có thể không siêu thanh lịch, nhưng hiệu quả:

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

Điều này chỉ gửi khóa xuống lựa chọn bạn muốn, trong trường hợp của chúng tôi, chúng tôi đang sử dụng modelSelector nhưng rõ ràng bạn có thể sử dụng bất kỳ bộ chọn nào khác.

Sau đó, trong mô hình đối tượng trang của tôi:

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

Và từ bài kiểm tra:

myPage.selectMyOption(1);

2

Vấn đề là các giải pháp hoạt động trên hộp chọn góc thông thường không hoạt động với Vật liệu góc md-select và md-option sử dụng thước đo góc. Bài này được đăng bởi một người khác, nhưng nó hiệu quả với tôi và tôi không thể bình luận về bài đăng của anh ấy (chỉ có 23 điểm đại diện). Ngoài ra, tôi đã dọn dẹp nó một chút, thay vì browser.sleep, tôi sử dụng 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
});

Tôi chỉ sử dụng cái này:element(by.model('selectModel')).click(); element(by.css('md-option[value="searchOptionValue"]')).click();
Luan Nguyen.

Dưới đây là cách tiếp cận khác: mdSelectElement.getAttribute('aria-owns').then( function(val) { let selectMenuContainer = element(by.id(val)); selectMenuContainer.element(by.css('md-option[value="foo"]')).click(); } );
gbruins

1

Có một vấn đề với việc lựa chọn các tùy chọn trong Firefox mà bản hack của Droogans đã khắc phục mà tôi muốn đề cập ở đây một cách rõ ràng, hy vọng nó có thể giúp ai đó tránh khỏi một số rắc rối: https://github.com/angular/protractor/issues/480 .

Ngay cả khi các bài kiểm tra của bạn đang vượt qua cục bộ với Firefox, bạn có thể thấy rằng chúng không thành công trên CircleCI hoặc TravisCI hoặc bất kỳ thứ gì bạn đang sử dụng cho CI & triển khai. Nhận thức được vấn đề này ngay từ đầu sẽ giúp tôi tiết kiệm rất nhiều thời gian :)


1

Người trợ giúp đặt thành phần tùy chọn:

selectDropDownByText:function(optionValue) {
            element(by.cssContainingText('option', optionValue)).click(); //optionValue: dropDownOption
        }


1

Chọn tùy chọn theo Chỉ mục:

var selectDropdownElement= element(by.id('select-dropdown'));
selectDropdownElement.all(by.tagName('option'))
      .then(function (options) {
          options[0].click();
      });

1

Tôi đã cải thiện một chút giải pháp do PaulL viết. Trước hết, tôi đã sửa mã để tương thích với API thước đo cuối cùng. Và sau đó tôi khai báo hàm trong phần 'onPrepare' của tệp cấu hình Protractor như một thành viên của phiên bản trình duyệt , vì vậy nó có thể được tham chiếu dưới dạng bất kỳ thông số e2e nào.

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

1

Tôi đã mò mẫm trên mạng để tìm câu trả lời về cách chọn một tùy chọn trong menu thả xuống mô hình và tôi đã sử dụng sự kết hợp này đã giúp tôi tìm ra tài liệu Angular.

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

có vẻ như khi ném tất cả mã vào một dòng, nó có thể tìm thấy phần tử trong menu thả xuống.

Mất rất nhiều thời gian cho giải pháp này, tôi hy vọng rằng điều này sẽ giúp ích cho ai đó.


0

Chúng tôi muốn sử dụng giải pháp thanh lịch ở đó bằng cách sử dụng tài liệu anglejs nhưng nó không hoạt động vì thực sự không có thẻ option / md-option trong DOM cho đến khi nhấp vào md-select. Vì vậy, cách "thanh lịch" đã không hoạt động với chúng tôi (lưu ý vật liệu góc cạnh!) Đây là những gì chúng tôi đã làm cho nó thay vào đó, không biết nó có phải là cách tốt nhất không nhưng nó chắc chắn đang hoạt động

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

Chúng tôi cần có 4 lựa chọn được chọn và trong khi lựa chọn đang mở, có một lớp phủ trong cách chọn lựa chọn tiếp theo. đó là lý do tại sao chúng ta cần đợi 500ms để đảm bảo rằng chúng ta không gặp rắc rối với các hiệu ứng vật chất vẫn đang hoạt động.


0

Một cách khác để đặt một phần tử tùy chọn:

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

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


});

0

Bạn có thể chọn các tùy chọn thả xuống theo giá trị: $('#locregion').$('[value="1"]').click();


0

Đây là cách thực hiện theo giá trị tùy chọn hoặc chỉ mục . Ví dụ này hơi thô thiển, nhưng nó chỉ ra cách làm những gì bạn muốn:

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

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

    })

}

0

Chúng tôi có thể tạo một lớp DropDown tùy chỉnh cho điều này và thêm một phương thức như sau:

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

Ngoài ra, để xác minh giá trị hiện đang được chọn, chúng ta có thể có:

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

0

Ví dụ dưới đây là cách dễ nhất. Tôi đã kiểm tra và vượt qua trong Phiên bản thước đo góc5.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

Mã đầy đủ

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

  });
});

0

Đây là một câu trả lời đơn giản một dòng, trong đó góc có bộ định vị đặc biệt có thể giúp chọn và lập chỉ mục từ danh sách.

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

Mặc dù mã này có thể giải quyết câu hỏi, bao gồm giải thích về cách thức và lý do tại sao điều này giải quyết vấn đề sẽ thực sự giúp cải thiện chất lượng bài đăng của bạn và có thể dẫn đến nhiều phiếu bầu hơn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ. Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những giới hạn và giả định nào được áp dụng. Từ đánh giá
double-beep

-1

Chọn tùy chọn theo thuộc tính CSS

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

hoặc là

element(by.css("#locregion")).element(by.css("[value='1']")).click();

Trong đó locregion (id), tổ chức.parent_id (tên kiểu máy) là các thuộc tính của phần tử chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.