Search code examples
javascriptunit-testingjasminei18nextaurelia

Intermittent unit-test failure associated with i18next


I am trying to unit test my aurelia custom element, which looks like below.

// BaseText.ts
import { bindable } from "aurelia-framework";
import { BaseI18N } from "aurelia-i18n";

export class BaseText extends BaseI18N {
    @bindable public value: string;
    @bindable public i18nKey: string;
}

// NormalText.ts
export class NormalTextCustomElement extends BaseText {}

// NormalText.html
<template>
    <span t.bind="i18nKey">${value}</span>
</template>

Now, I want to test if I change the value of i18nKey, the translated text is shown in the element. To test that, I have written the below test case.

describe("i18n specs", () => {

    let component;
    beforeEach(() => {
        component = StageComponent
            .withResources("NormalText/NormalText")
            .inView("<normal-text id='i18n1' value='Ignored Text' i18n-key='test'></normal-text>");

        component.bootstrap((aurelia: Aurelia) => aurelia.use
            .standardConfiguration()
            .plugin(PLATFORM.moduleName("aurelia-i18n"), (instance) => {
                const aliases = ["t"];
                TCustomAttribute.configureAliases(aliases);

                return instance.setup({
                    attributes: aliases,
                    fallbackLng: "en",
                    lng: "en",
                    resources: {         //<-- translation resources
                        en: {
                            translation: {
                                test: "English test"
                            }
                        }
                    }
                });
            }));

    });

    it("Should render the translated text with a i18nKey", (done) => {
        component
            .create(bootstrap)
            .then(() => {
                const spanElement = document.querySelector('normal-text#i18n1>span');
                expect(spanElement.textContent.trim()).toBe('English test');
            })
            .catch(e => { console.log(e.toString()) })
            .finally(() => {
                component.dispose();
                done();
            });
    });
});

Now the problem is that this test case fails intermittently, which surely is going to be a problem with CI. I suspect that it has something to do it the initialization of i18next, and the test case is running before the initialization is complete. Though I am not very sure about this hypothesis.

What should I change, so that this test case becomes deterministic?

Additional info:

  1. This test case succeeds if it runs before every other view related test cases.
  2. I have created a GitHub repo, so that interested reader/user can reproduce the problem. Please keep in mind that you might have run the tests multiple times to replicate the issue.

Solution

  • Turned out that the issue is actually related to how I was writing the test cases.

    Previously I had structured it as below.

    describe("View specs", ()=> {
      // here goes other test suite and/or test cases
      describe("i18n specs", () => {
    
        let component;
        beforeEach(() => {
          // here goes the custom initialization code of aurelia, as shown in question
        });
      });
    });
    

    I think this custom initialization code was interfering with the other test cases with default bootstrapping. I simply pulled out the beforeEach from the i18n specs and put it directly under the View specs test suite. Which means that all of the test cases under View specs test suite are using same aurelia bootstrapping setup. And actually that did solve my problem.