1

I'm writing some e2e tests with protractor. My application is an Angular Material 2 application. In my test I want to select an option of a md-select by value. When I inspect the open md-select I see the md-option items. The values of the options are in an attribute ng-reflect-value.

Let's say I have an option with the value "optionA". How can I select a certain option by this value?

I tried this:

element(by.name('myselect')).click();
$$('.mat-option').then((options) => {
  ...
});

and inside then I see the correct number of options, but how can I select the option which has the value "opetionA" ?

Edric
  • 24,639
  • 13
  • 81
  • 91
Ralf Schneider
  • 651
  • 1
  • 8
  • 15
  • Just curious, why do you want to select an option based on a non-visible value for a customer during E2E tests? Isn't it better to use the visible value, this is explained in [this](https://stackoverflow.com/questions/44073870/trouble-locating-angular-element-for-protractor-ui-nav-test/44089777#44089777) answer – wswebcreation May 29 '17 at 05:55
  • 1
    Yes, you're right. That might be the better solution. – Ralf Schneider May 30 '17 at 05:30

3 Answers3

7

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>

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

selectOptionByOptionValue('your-id', '1');
KVarmark
  • 226
  • 3
  • 4
3

What you can do is make your css-selector "dynamic" by adding the expected value in the selector. For example

// I've place the expected value in a var to make it more clear
const optionValue = 'your-option-value';

// Open select
element(by.name('myselect')).click();
// Click on the option with your selected value
$(`.mat-option[value="${optionValue}"]`).click();

I hope this helps.

wswebcreation
  • 2,365
  • 2
  • 10
  • 18
  • 1
    value is not an attribute of a in Angular Material 2. But this works for me: $('.mat-option[ng-reflect-value="optionA"]').click(); – Ralf Schneider May 30 '17 at 05:33
3

This works for me:

    element.all(by.cssContainingText('span.mat-option-text', "option text to search for")).click();

Got answer from this question: How to locate element by span value in protractor?

jvhang
  • 747
  • 6
  • 19