Search code examples
javascripttestingautomated-testse2e-testingtestcafe

TestCafe - Select option in <select>


I have a <select> with several <option> tags. Some of them are disabled by using the class 'is-disabled'. What I want to do is select the first available option in the list. For this, I used an example that I found on the testcafe website (https://devexpress.github.io/testcafe/documentation/recipes/testing-select-elements.html) but I can't seem to get it to work.

When running the test, the tool performs a click on the select and a second one after which it closes. After this, no value is selected.

Is there a better way to handle the dynamic selection of an option? Or what would be a better solution? Any help would be greatly appreciated!

regards Cornel

SizeSelector component:

import {t, Selector} from 'testcafe';

class SizeSelector {

  constructor() {
    this._sizeSelector = Selector('.sizeSelectionGroup');
    this._selectors = this._sizeSelector.child('.productSizeSelection');
    this._widthSelector = this._selectors.nth(0);

    // todo other size types (single numeric/text)
  }

  // todo refactor
  async setFirstAvailableWidth() {
    const options = this._widthSelector.find('option'); // contains 13 elements while debugging
    const availableOptions = options.filter(node => {
      return !node.classList.contains('is-disabled');
    });

    const count = await availableOptions.count; // contains around 8 elements while debugging
    if (count > 0) {
      return await t
        .click(this._widthSelector)
        .click(availableOptions.nth(0))
        .expect(this._lengthSelector.value).ok(); // fails with value undefined
    }

    throw new Error('No available width found.');
  }
}

export default SizeSelector;

Solution

  • So I am not sure if this will work for you exactly in your situation. I tried to simulate a dropdown which had several options using the class 'is-disabled' and made a test with a function that will click the very first option in the dropdown that is not disabled I based the function off this

    Here is the example dropdown I made

    https://jsfiddle.net/L6p2u/190/

    Here is the test code (Orange should be the first option that isn't disabled)

    import { Selector, t } from 'testcafe';
    
    fixture `testcafe canvas`
        .page `https://jsfiddle.net/L6p2u/190/`;
    
    const medwait            = 5000
    const longwait           = 15000;
    const dropdown           = Selector('#colour');
    
    async function selectFirstAvailableOption(selector) {
        const select = selector;
        await t // select the first available option
            .setTestSpeed(0.7)
            .hover(select)
            .expect(select.hasAttribute("disabled")).notOk({timeout: 5000})
            .click(select)
            .click(select
                .find("option")
                .filter((node) => {
                    if (node && node.className.indexOf('is-disabled') == -1) {
                        return true;
                    }
                    return false;
                })
                .nth(0)).wait(5000); // this wait is just so you can see
    }
    
    test('Instructor', async t => {
        await t
            .switchToIframe('[name="result"]')
        await selectFirstAvailableOption(dropdown);
    });