1

I've started to use Detox to create automation UI testing for our react-native app (here testing on iOS).

I've noticed that Detox (or Jest) times out randomly. The exact same test sometimes passes, but some other time it get stuck and doesn't continue running the test. Once the jest timeout is over I get the following error

Timeout - Async callback was not invoked within the 40000ms timeout specified by jest.setTimeout.

  47 |     });
  48 |     describe('when the user taps on the payment history tab', () => {
> 49 |       it('should go on the payment history view', async () => {


  at Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:92:20)
  at Suite.<anonymous> (e2e/tests/loans/index.test.js:49:7)

One of my test looks like this:

  it('should go on the payment history view', async () => {
    await element(by.id('product-tab-2')).tap();
    await waitFor(element(by.id('product-payment-history-1')))
      .toBeVisible()
      .withTimeout(5000);
    await expect(element(by.id('product-payment-history-1'))).toBeVisible();
  });

I've attempted to use the "trace" flag to see if there were any details about why it gets stuck. It seems like some invoke calls are skipped and it tries to execute the following test before it actually finished the previous one.

I don't think it's an issue with the tests themselves as they happen to all run 3 out of 4 times I'd say.

Does anyone have this issue? Is there a way to fix it? Or is there a way to restart the test set if something freezes?

Thanks!

alexmngn
  • 9,107
  • 19
  • 70
  • 130

1 Answers1

1

From the detox documentation for waitFor

NOTE: waitFor will not throw when reaching timeout, instead it will just continue to the next line. To make sure your tests work as you expect them to add expect() at the following line

If you use waitFor you should put the expect for the same element right after the wait for because of the above. Maybe try adjusting your test to the following:

it('should go on the payment history view', async () => {
  await element(by.id('product-tab-2')).tap();
  await waitFor(element(by.id('product-payment-history-1')))
    .toBeVisible()
    .withTimeout(5000);
  await expect(element(by.id('product-payment-history-1'))).toBeVisible();
  await expect(element(by.id('product-payment-history'))).toBeVisible();
});

This will avoid the test moving on and looking for the next item without the waitFor item showing up

ageoff
  • 2,798
  • 2
  • 24
  • 39
  • This is exactly what I'm doing. Not only this test fails, it randomly stop to any test. – alexmngn Feb 14 '19 at 16:25
  • You are waiting for 'product-payment-history-1' though and then checking for 'product-payment-history'. You should add a check after you wait for 'product-payment-history-1'. And you should do that anywhere you have a waitFor. Always follow a waitFor with the exact expect of the waitFor. – ageoff Feb 14 '19 at 16:31
  • Was a typo, I fixed the initial question – alexmngn Feb 14 '19 at 16:34