schickling/chromeless

Chromeless.wait(timeout) is not waiting

tux4 opened this issue · 4 comments

tux4 commented

This is a Bug Report

Description

Based on the API documentation here https://github.com/graphcool/chromeless/blob/master/docs/api.md#api-wait-timeout calling await chromeless.wait(timeout) should wait for the given timeout before continuing. But it doesn't seem to wait. This issue also seems to effect wait(selector).

I have created a minimal case to reproduce this bug here - https://github.com/tux4/chromeless-bug . Here is a summary -

The following test cases in jest should behave in similar manner -

const { Chromeless } = require("chromeless");

const chromeless = new Chromeless();

function myWait(time=3000) {
  return new Promise((resolve) => {
    setTimeout(resolve, time);
  });
}

describe("Reproduce bug", () => {
  it("this should wait for 3 seconds but it doesn't", async () => {
    await chromeless.wait(3000);
  });

  it("this should wait for 3 seconds and it does", async () => {
    await myWait(3000);
  });
});

afterAll(async () => {
  await chromeless.end();
});

However, the first test ends in 2ms while the second test takes over 3s:

➜  chromeless-bug yarn test
yarn test v1.0.2
$ yarn jest
 PASS  __tests__/wait-test.js (6.676s)
  Reproduce bug
    ✓ this should wait for 3 seconds but it doesn't (2ms)
    ✓ this should wait for 3 seconds and it does (3001ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        7.161s
Ran all test suites.
Done in 7.99s.

Similar or dependent issues:

Additional Data

Node Version - 8.5.0
Chromeless - 1.4.0
OS - Ubuntu 16.04.3 LTS

I also see a similar behaviour in which:

      browser = await chromeless
        .wait(".foo")
        .exists(".foo")
        .click(".foo");

Will sometimes 'appear' to click .foo before actually waiting for it, so the test will hung.

I am then splitting this code into:

      browser = await chromeless
        .wait(".foo")
        .exists(".foo")
      browser = await chromeless.click(".foo");

And that does it

o0101 commented

Maybe something that is happening is, the command chaining syntax is not actually executing the commands. It is just pushing each command and arguments into a queue.
Commands are only executed when chromeless.end() is called, I think.

+1. An example of my code:

console.log(new Date())
  await browser
    .wait('nav[role="navigation"] form input')
    .evaluate(() => {
      // Things here
    })

  await browser.wait(20000)

  await browser.setFileInput('nav[role="navigation"] form input', '/myfile.jpg')
  console.log(new Date())

I was excepting to see the second new Date after 20s, but instead it appears immediately:

2018-04-27T10:55:51.037Z
2018-04-27T10:55:52.547Z

If you chain the methods, it won't work anyway and, using await browser.end(), you can see that the 20000ms are put AT THE END of the process, not between them.

I think you can solve writing this:

// Code

await sleep(3000)

// Other code

function sleep(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms)
  })
}
o0101 commented