Bagaimana memilih opsi dalam tes drop down protractorjs e2e


121

Saya mencoba memilih opsi dari drop-down untuk tes e2e sudut menggunakan busur derajat.

Berikut adalah cuplikan kode dari opsi pilih:

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

Saya telah mencoba:

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

Ini memberi saya kesalahan berikut:

String tidak valid atau ilegal telah ditentukan Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01' System info: os.name: 'Mac OS X' , os.arch: 'x86_64', os.version: '10 .9 ', java.version:' 1.6.0_65 'Info driver: driver.version: tidak diketahui

Saya juga telah mencoba:

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

Ini memberi saya kesalahan berikut:

ElementNotVisibleError: Elemen saat ini tidak terlihat sehingga mungkin tidak berinteraksi dengan Durasi perintah atau waktu tunggu: 9 milidetik Info pembuatan: versi: '2.35.0', revisi: 'c916b9d', waktu: '2013-08-12 15:42: 01 'Info sistem: os.name:' Mac OS X ', os.arch:' x86_64 ', os.version: '10 .9', java.version: '1.6.0_65' ID Sesi: bdeb8088-d8ad-0f49-aad9 -82201c45c63f Info driver: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform = MAC, acceptSslCerts = true, javascriptEnabled = true, browserName = firefox, rotatable = false, locationContextEnabled = true, version = 24.0, cssSelectorsEnabled = true, database, cssSelectorsEnabled = true, database = benar, handleAlerts = true, browserConnectionEnabled = true, nativeEvents = false, webStorageEnabled = true, applicationCacheEnabled = false, takeScreenshot = true}]

Adakah yang bisa membantu saya dengan masalah ini atau menjelaskan apa yang mungkin saya lakukan salah di sini.

Jawaban:


88

Saya memiliki masalah serupa, dan akhirnya menulis fungsi pembantu yang memilih nilai dropdown.

Saya akhirnya memutuskan bahwa saya baik-baik saja memilih berdasarkan nomor opsi, dan oleh karena itu menulis metode yang mengambil elemen dan nomor pilihan, dan memilih nomor pilihan itu. Jika optionNumber adalah null, ia tidak memilih apa-apa (membiarkan dropdown tidak dipilih).

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

Saya menulis posting blog jika Anda ingin lebih detail, itu juga mencakup verifikasi teks dari opsi yang dipilih di dropdown: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/


1
Tidak berhasil untuk saya, dapatkan element.findElements bukanlah sebuah fungsi.
Justin

251

Bagi saya bekerja seperti pesona

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

Semoga membantu.


2
Catatan kecil - hanya v0.22 (Saya baru saja mengganti kode saya dengan ini hari ini, dan harus meningkatkan versi untuk mendapatkannya)
PaulL

Adakah cara untuk menargetkan elemen menggunakan ini? Seperti memiliki menu pilihan negara duplikat.
Christopher Marshall

11
Christopher, ElementFinderdapat berantai, jadi Anda dapat melakukan:element(by.css('.specific-select')).element(by.cssContainingText('option', 'BeaverBox Testing')).click();
Joel Kornbluh

6
Perhatikan bahwa Anda bisa mendapatkan kecocokan parsial, jadi 'Kecil' akan cocok dengan 'Ekstra Kecil'.
TrueWill

3
Untuk menambah komentar TrueWill: Sisi buruk dari solusi ini adalah jika Anda memiliki dua opsi serupa, ia akan menggunakan opsi yang ditemukan terakhir - yang memunculkan kesalahan berdasarkan pilihan yang salah. Apa yang berhasil untuk saya adalah stackoverflow.com/a/25333326/1945990
Mike W

29

Pendekatan elegan akan melibatkan pembuatan abstraksi yang mirip dengan apa yang ditawarkan oleh binding bahasa selenium lainnya di luar kotak (misalnya Selectkelas dalam Python atau Java).

Mari buat pembungkus yang nyaman dan sembunyikan detail implementasi di dalamnya:

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;

Contoh penggunaan (perhatikan seberapa mudah dibaca dan digunakan):

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

Solusi diambil dari topik berikut: Pilih -> opsi abstraksi .


FYI, membuat permintaan fitur: Pilih -> opsi abstraksi .


Mengapa Anda menggunakan 'return' dalam fungsi tertentu? Apa itu perlu?
Michiel

1
@Ichiel poin yang bagus. Mungkin diperlukan jika Anda ingin secara eksplisit menyelesaikan janji yang dikembalikan oleh click(). Terima kasih.
alecxe

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

1
Itu yang paling benar untuk saya. Dengan cssContainingText tidak Anda memastikan untuk menangkap bidang yang diinginkan. Bayangkan jika Anda memiliki 2 kotak pilih dengan nilai yang sama. +1
YoBre

4
Maaf, apa itu BKN01?
Gerfried

1
@Gerfried BKN01 adalah teks yang ingin Anda pilih dari menu drop-down.
MilanYadav

@GalBracha Maaf tidak membuat Anda
MilanYadav

Jika Anda memiliki opsi lain yang menggunakan prefex yang sama dengan BKN01, itu tidak akan berfungsi. Yang acak akan diambil.
zs2020

15

Untuk mengakses opsi tertentu, Anda perlu menyediakan selektor nth-child ():

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

Ini tidak memberikan jawaban atas pertanyaan tersebut. Untuk mengkritik atau meminta klarifikasi dari seorang penulis, tinggalkan komentar di bawah postingannya.
jpw

@jpw adalah jawaban saya salah. atau apakah itu hanya rumusan jawaban saya yang salah?
bekite

Rumusan jawaban sebagai pertanyaan adalah mengapa. Saya tidak tahu apakah itu jawaban yang benar. Jika ya, Anda harus merumuskannya seperti itu.
jpw

3
@bekite Tidak bekerja untuk saya.Masih mendapatkan kesalahan Elemen Kesalahan tidak terlihat ketika saya mencoba saran Anda
Ranjan Bhambroo

8

Beginilah cara saya melakukan pilihan saya.

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

5

Inilah cara saya melakukannya:

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

Untuk menunggu angular selesai menunggu pemrosesan, gunakan waitForAngular()metode busur derajat .
Avi Cherry

5

Coba ini, ini berhasil untuk saya:

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

4

Anda dapat mencoba ini semoga berhasil

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

Cara lain untuk mengatur elemen opsi:

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

var orderTest = elemen (by.model ('ctrl.supplier.orderTest')) orderTest. $ ('[value = "1"]'). click (); saya mendapatkan kesalahan Oleh (pemilih css, [value = "3"])
Anuj KC

3

Untuk memilih item (opsi) dengan id unik seperti di sini:

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

Saya menggunakan ini:

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

3

Kami menulis perpustakaan yang mencakup 3 cara untuk memilih opsi:

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>

Fitur tambahan dari fungsi ini adalah mereka menunggu elemen untuk ditampilkan sebelum tindakan apa pun di select dilakukan.

Anda bisa menemukannya di npm @ hetznercloud / protractor-test-helper . Pengetikan untuk TypeScript juga disediakan.


2

Mungkin tidak super elegan, tapi efisien:

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

Ini hanya mengirimkan kunci ke bawah pada pilihan yang Anda inginkan, dalam kasus kami, kami menggunakan modelSelector tetapi jelas Anda dapat menggunakan selektor lain.

Kemudian di model objek halaman saya:

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

Dan dari pengujian:

myPage.selectMyOption(1);

2

Masalahnya adalah bahwa solusi yang bekerja pada kotak pilih bersudut biasa tidak bekerja dengan md-select dan md-option Angular Material menggunakan busur derajat. Yang ini telah diposting oleh orang lain, tetapi berhasil untuk saya dan saya belum dapat mengomentari postingannya (hanya 23 poin rep). Juga, saya membersihkannya sedikit, daripada browser.sleep, saya menggunakan 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
});

Saya hanya menggunakan ini:element(by.model('selectModel')).click(); element(by.css('md-option[value="searchOptionValue"]')).click();
Luan Nguyen

Berikut pendekatan lain: mdSelectElement.getAttribute('aria-owns').then( function(val) { let selectMenuContainer = element(by.id(val)); selectMenuContainer.element(by.css('md-option[value="foo"]')).click(); } );
gbruins

1

Ada masalah dengan memilih opsi di Firefox yang diperbaiki peretasan Droogans yang ingin saya sebutkan di sini secara eksplisit, berharap itu bisa menyelamatkan seseorang dari beberapa masalah: https://github.com/angular/protractor/issues/480 .

Meskipun pengujian Anda berhasil secara lokal dengan Firefox, Anda mungkin menemukan bahwa pengujian tersebut gagal di CircleCI atau TravisCI atau apa pun yang Anda gunakan untuk CI & penerapan. Menyadari masalah ini sejak awal akan menghemat banyak waktu saya :)


1

Pembantu untuk menyetel elemen opsi:

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


1

Pilih opsi berdasarkan Indeks:

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

1

Saya telah sedikit meningkatkan solusi yang ditulis oleh PaulL. Pertama-tama saya memperbaiki kode agar kompatibel dengan API Protractor terakhir. Dan kemudian saya mendeklarasikan fungsi di bagian 'onPrepare' dari file konfigurasi Protractor sebagai anggota instance browser , sehingga dapat direferensikan dari spesifikasi e2e apa pun.

  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

Saya telah menjaring internet untuk mendapatkan jawaban tentang bagaimana memilih opsi dalam model dropdown dan saya telah menggunakan kombinasi ini yang telah membantu saya dengan materi Angular.

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

Tampaknya saat membuang kode semua dalam satu baris, ia dapat menemukan elemen di tarik-turun.

Butuh banyak waktu untuk solusi ini, saya harap ini membantu seseorang.


0

Kami ingin menggunakan solusi elegan di atas sana dengan menggunakan material angularjs tetapi tidak berhasil karena sebenarnya tidak ada tag opsi / md-opsi di DOM hingga md-pilih telah diklik. Jadi cara "elegan" tidak berhasil untuk kami (perhatikan bahan bersudut!) Inilah yang kami lakukan untuk itu, tidak tahu apakah ini cara terbaik tetapi pasti berfungsi sekarang

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

Kami perlu memiliki 4 pilihan yang dipilih dan saat pilihan terbuka, ada overlay dalam cara memilih pilihan berikutnya. itulah mengapa kita perlu menunggu 500ms untuk memastikan kita tidak mendapat masalah dengan efek material yang masih beraksi.


0

Cara lain untuk mengatur elemen opsi:

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

Anda dapat memilih opsi dropdown berdasarkan nilai: $('#locregion').$('[value="1"]').click();


0

Berikut adalah cara melakukannya dengan nilai opsi atau indeks . Contoh ini agak kasar, tetapi menunjukkan cara melakukan apa yang Anda inginkan:

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

Kita dapat membuat kelas DropDown khusus untuk ini dan menambahkan metode sebagai:

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

Juga, untuk memverifikasi nilai apa yang saat ini dipilih, kita dapat memiliki:

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

0

Contoh di bawah ini adalah cara termudah. Saya telah menguji dan lulus dalam Versi Protractor5.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

Kode lengkap

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

Ini adalah jawaban satu baris sederhana di mana sudut memiliki pelacak khusus yang dapat membantu memilih dan mengindeks dari daftar.

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

Meskipun kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan memberikan indikasi batasan dan asumsi apa yang berlaku. Dari Ulasan
double-beep

-1

Pilih opsi berdasarkan properti CSS

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

atau

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

Di mana locregion (id), organization.parent_id (nama model) adalah atribut elemen pilih.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.