3

I use Testcafe to test a website which is using the jquery plugin Chosen and I want to make an assertion in my test code depending on a value returned by an external helper function (getSelectedOption).

This function gets a Chosen Selector as a parameter and should return the selected value to the assertion, but the function always returns the first element of the list instead of the chosen one.

When I use the function code in my test, everything works fine. It seems that the function doesn't have the actual state about the HTML data and can't see that an element is already selected.

This is a snippet from the test code:

await t
 .click(await getOptionByText('salutation', 'Frau'))
 .expect(await getSelectedOption('gender')).eql('weiblich')

This is a snippet from the external functions:

export const getChosenSelectorFromName = selectName => `#${selectName}_chosen`;

        export const getSelectedOption = async selectName => {
          const selectedOptionText = await 
     Selector(getChosenSelectorFromName(selectName))
            .find('.chosen-single')
            .innerText;
          return selectedOptionText.toLowerCase().trim()
        };

        export const getOptionByText = async (selectName, optionText) => {
          const chosenSelectorString = getChosenSelectorFromName(selectName);
          await t.click(Selector(chosenSelectorString));
          return await Selector(chosenSelectorString)
            .find('.chosen-drop')
            .find('li')
            .withText(optionText);
        };

When I use similar code like the getSelectedOption function inside my test, everything works fine:

const genderSelect = Selector('#gender_chosen);

.click(await getOptionByText('salutation', 'Frau'))
       .expect(genderSelect.innerText).eql('WEIBLICH')
Alex Skorkin
  • 4,264
  • 3
  • 25
  • 47
Tizian
  • 31
  • 1

1 Answers1

3

If you call await Selector(<some value>) then TestCafe immediately retries the data from the web page at the current moment. You can tell TestCafe to retry data from web page until it becomes equal to the expected value. To do it, you need to move the DOM manipulation function into ClientFunction:

import { Selector, ClientFunction } from "testcafe";

fixture `Fixture`
        .page('https://harvesthq.github.io/chosen/');

const getChosenSelectorFromName = selectName => `#${selectName}_chosen`;

const getSelectedOption = ClientFunction(selector => {
    var choosenDiv    = document.querySelector(selector);
    var singleValueEl = choosenDiv.querySelector('.chosen-single');

    return singleValueEl.innerText;
});


test('test', async t => {
    await t.expect(getSelectedOption('.chosen-container')).eql('Choose a Country...');
}); 
mlosev
  • 5,130
  • 1
  • 19
  • 31
  • Thank you very much for your reply, it works :) But is it not possible to call another function inside the ClientFunction? I still want to use my "getChosenSelectorFromName" function but I get a ReferenceError "getChosenSelectorFromName is not defined". – Tizian May 09 '19 at 11:41
  • You can call the `getChosedSelectorFromName` function. You need to pass this function as a dependency of your ClientFunction. Please take a look at the following example: https://devexpress.github.io/testcafe/documentation/test-api/obtaining-data-from-the-client/#import-functions-to-be-used-as-client-function-dependencies – Alex Kamaev May 13 '19 at 13:31