Pending operations in playwright on nodejs - javascript

I'm trying to get a new page at the moment of clicking on the link:
await test.step(`Step name`, async () => {
const [newPage] = await Promise.all([
context.waitForEvent('page'),
page.click('//span[normalize-space(#title)=\'Bup\']')
]);
}
And I get this page. Further operations with this instance are successful. But after 30 seconds the test ends with the following error:
Timeout of 30000ms exceeded.
Pending operations:
- browserContext.waitForEvent at "path to the file":48:21
- at <unknown>
I will assume that it is related to a promise, but I do not understand what exactly the problem is. Help is needed.
Playwright v14.0, nodejs v16.7.0.
I run the tests with the following command: npx playwright test tests/diag.spec.mjs --headed
A strange observation. When I run it in debug mode, there is no such error
:
PWDEBUG=1 npx playwright test tests/diag.spec.mjs

Ok, I found the answer, but it's a little weird. You need to increase the timeout in the playwright config:
https://github.com/microsoft/playwright/issues/8268
Also you can add test.slow() https://playwright.dev/docs/api/class-test#test-slow

Related

closing open handles detected by jest

i am writting tests for a node application which uses bull to process background jobs.
the test seems to be passing and working as expected but i am seeing the following error message
Jest has detected the following
8 open handles potentially keeping
Jest from exiting:
the log points to specifically this line and other similar statements.
const csvExportsQueue = ['test', 'development'].includes(process.env.NODE_ENV) ? new Queue('exports') : new Queue('csv exports', 'redis://redis:6379/13');
I tried to add the below statement to my test but it still gives the same error
afterAll(async () => {
await new Promise(resolve => setTimeout(() => resolve(), 10000)); // avoid jest open handle error
});
any help on how to fix this will be great, thanks.
add "jest --detectOpenHandles" to "test" in package.json to see the openhandles for Debugging
check your db connection (most likely) and close it them with connection.end()

Jest Call retries were exceeded

I have error in the following below test. My node version is : v12.10.0. is there any alternative of setTimeout?
test('demo code', async () => {
const cc = await projectSetup(project);
const onNotification = jest.fn();
cc.sendNotification();
await waitForExpect(() => {
expect(onNotification).toHaveBeenCalledTimes(2);
});
});
The Error log is as
Call retries were exceeded
at ChildProcessWorker.initialize (../../../node_modules/jest-worker/build/workers/ChildProcessWorker.js:230:21)
just add jest.useFakeTimers(); after your imports
...
jest.useFakeTimers();
test('demo code', async () => {
const cc = await projectSetup(project);
const onNotification = jest.fn();
cc.sendNotification();
await waitForExpect(() => {
expect(onNotification).toHaveBeenCalledTimes(2);
});
});
it works in my code
In my case, the actual problem was with the promise handling.
I got the same issue when I was running all my test cases in one go with the jest.
Solution:
Try running one test separately then see what error is coming.
I got the below error after running one problematic test separately where earlier I was getting the Call retries were exceeded:
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "TypeError: Cannot read property 'code' of undefined".] {
code: 'ERR_UNHANDLED_REJECTION'
}
With this, I was sure that the problem is with the catch block and when I added it in the async service API function then the test case worked perfectly fine.
Maybe you can also try the same and see if it works for you or not.
I am using the below config:
node: 15.13.0
npm: 7.8.0
jest: 26.6.3
Try running npm doctor using the latest npm version. It's a great tool and it helped me diagnose permission and ownership issues right away.
Takeaway:
Verify File/Folder Permissions & Ownership
Encountered same error when updating the vue-jest version to below listed versions
#vue/vue3-jest: ^27.0.0-alpha.4
#vue/cli-plugin-unit-jest: ~5.0.0,
node: v17.9.0 or v16.14.2
Error disappeared, once downgraded it to node version v14.x.x
Hunch is - the latest node versions are not compatible with the dependencies.
I was able to run the test's successfully doing the following;
Install npm i -D jest-canvas-mock
Update the jest.config.ts file to have:
export default {
...
testEnvironment: "jsdom",
setupFiles: ["jest-canvas-mock"],
}

Mocha test not running the `try..finally` clause

I am running my Node.js tests with Mocha. When I add a try..finally clause I expect that Mocha will run the finally bit after the test. It works with errors and exceptions, but not when the test times out.
The tests below show the issue in detail.
describe('try-finally', () => {
it('should run finally with an error', async() => {
console.log('starting')
try {
console.log('started')
throw new Error('Error!')
console.log('finished')
} finally {
console.log('finally!')
}
});
it('should run finally with a timeout', async() => {
console.log('starting')
try {
console.log('started')
await timeout()
console.log('finished')
} finally {
console.log('finally!')
}
});
});
function timeout() {
return new Promise(ok => {
setTimeout(ok, 10*1000)
})
}
To run the test: save into a file try-finally.js, install Mocha with npm install -g mocha and then run test with mocha --exit try-finally.js. Output:
$ mocha --exit try-finally.js
try-finally
starting
started
finally!
1) should run finally with an error
starting
started
2) should run finally with a timeout
0 passing (2s)
2 failing
1) try-finally
should run finally with an error:
Error: Error!
at Context.it (try-finally.js:9:13)
2) try-finally
should run finally with a timeout:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. /home/alex/devo/batrasio/try-finally.js)
Both tests fail; the first one runs the finally clause and displays "finally!", while the second times out (waits for 10s when the test default timeout is 2s) and does not run the finally clause.
A couple of searches on Google and here on Stack Overflow yielded nothing. What am I doing wrong? Is this even possible, or do I need to use the obnoxious beforeEach() and afterEach() functions?
The finally block will run after the contents of the try block, not necessarily the whole test. Things like errors and exceptions are meant to be caught in the try block but with a timeout, the error is thrown by mocha (so outside of your try block).
If you need to run the finally block after the test is finished and it is taking too long, you can change the default timeout by putting
this.timeout(<insert time in ms>);
inside of your it function (or the describe function if you want it to apply to everything).
If you are wanting to do the same thing after every test, then yes the afterEach() function is the way to go.

JEST: "Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.", despite it being already configured

Before you point it out, yes, I know this seems like a likely duplicate of multiple questions like;
JEST: Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout
Got Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout
However, I implemented all 3 fixes suggested;
Use jest.setTimeout() inside the test to set the async timeout
Use the third parameter of test() to pass in an extended async timeout limit
Call the done function when complete
However, when running my jest test on an automated linux machine (Jenkins), it's still throwing the same error. Also, it's worth mentioning this works fine on my MacOS machine running NodeJS v10, while the automated linux machine runs NodeJS V8.8.3 (the latest LTS version)
This is what my jest test looks like;
const webdriverio = require('webdriverio');
const options = {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
args: ["--no-sandbox", "disable-web-security", "--disable-dev-shm-usage"]
}
}
};
const client = webdriverio.remote(options);
beforeEach(async () => {
await client.init();
})
test('Google Search for WebdriverIO has correct title', async (done) => {
jest.setTimeout(30000)
await client.url('https://www.google.com/ncr');
await client.setValue('input[name=q]', 'WebdriverIO');
await client.click('input[value="Google Search"]');
const title = await client.getTitle();
expect(title).toBe('WebdriverIO - Google Search');
done();
}, 30000);
afterEach(async () => {
await client.end();
});
And here is the log I get when I try to run the test;
09:57:19 > jest --config jest.config.js
09:57:19
09:57:20 Installing selenium server ...
09:57:22 Starting selenium server ...
09:57:23 Selenium server started ...
09:57:29 FAIL jest/test/google.spec.js (5.874s)
09:57:29 ��� Google Search for WebdriverIO has correct title (5016ms)
09:57:29
09:57:29 ��� Google Search for WebdriverIO has correct title
09:57:29
09:57:29 Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
09:57:29
09:57:29 at mapper (node_modules/jest-jasmine2/build/queue_runner.js:41:52)
09:57:29
09:57:29 ��� Google Search for WebdriverIO has correct title
09:57:29
09:57:29 A session id is required for this command but wasn't found in the response payload
09:57:29
09:57:29 at new RuntimeError (node_modules/webdriverio/build/lib/utils/ErrorHandler.js:143:12)
09:57:29 at RequestHandler.createOptions (node_modules/webdriverio/build/lib/utils/RequestHandler.js:121:23)
09:57:29 at RequestHandler.create (node_modules/webdriverio/build/lib/utils/RequestHandler.js:212:43)
09:57:29 at Object.url (node_modules/webdriverio/build/lib/protocol/url.js:24:32)
09:57:29 at Object.exec (node_modules/webdriverio/build/lib/helpers/safeExecute.js:28:24)
09:57:29 at Object.resolve (node_modules/webdriverio/build/lib/webdriverio.js:191:29)
09:57:29 at lastPromise.then.resolve.call.depth (node_modules/webdriverio/build/lib/webdriverio.js:486:32)
09:57:29 at _fulfilled (node_modules/q/q.js:854:54)
09:57:29 at self.promiseDispatch.done (node_modules/q/q.js:883:30)
09:57:29 at Promise.promise.promiseDispatch (node_modules/q/q.js:816:13)
09:57:29
09:57:29 Test Suites: 1 failed, 1 total
09:57:29 Tests: 1 failed, 1 total
09:57:29 Snapshots: 0 total
09:57:29 Time: 5.988s, estimated 7s
09:57:29 Ran all test suites.
09:57:29 Killing selenium server ...
Any thoughts on why this could fail while it works fine on my local machine would be greatly appreciated. Also, I tried setting jest.setTimeout inside my Jest global setup file, but it throws jest.setTimeout is not a function;
https://github.com/facebook/jest/issues/3788
I had something similar in my tests. My tests passed fine locally but failed on GitHub Actions.
My problem was that locally, Test tools were already downloaded (in my case, in-memory MongoDB. In your case, the chrome browser), but on the remote environment, they had to download first.
Check your Jenkins logs for your environment downloading chrome, and the test fails before the download reaches 100%. Even if you don't find that, the logs you published in the question kinda hint in that direction, because the log prints out that the timeout is set to 5000ms, even though you set the timeout for the first test to a different value:
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
This tells me that the part of the test that timed-out, was the part before the test.
To solve this, you need to specifically add a longer timeout to the beforeEach function, where you initialize webdriver. This way, on the first test, when chrome is being downloaded, you'll get enough time to finish downloading chrome. On the next tests, this should not be an issue since chrome is already available.
It's also recommended to actively download the chrome\chromium browser in Jenkins so it will be available even before the test run starts.
So, I suggest you try this:
const webdriverio = require('webdriverio');
const options = {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
args: ["--no-sandbox", "disable-web-security", "--disable-dev-shm-usage"]
}
}
};
const client = webdriverio.remote(options);
beforeEach(async () => {
await client.init();
}, 30000) // <-- This is what you need. not the timeout in the actual test
test('Google Search for WebdriverIO has correct title', async () => {
jest.setTimeout(30000); // you can keep this if you think is needed,
// but I'm pretty sure it's not
await client.url('https://www.google.com/ncr');
await client.setValue('input[name=q]', 'WebdriverIO');
await client.click('input[value="Google Search"]');
const title = await client.getTitle();
expect(title).toBe('WebdriverIO - Google Search');
});
afterEach(async () => {
await client.end();
});
Here's an example of an old run, failing because the in-memory db didn't finish downloading before the timeout. This results in the tests starting even though the database isn't ready yet for use.
After adding the timeout to my beforeEach functions, it stopped happening.
If you're still facing the problem after the suggested fix, feel free to comment on this answer. If this was the correct answer, please don't forget to mark the answer :-)

Mocha: Error Timeout of 2000ms exceeded

I am trying to seed the database for unit test.
Below is the seed.js file:
.......
const app = require('./app')
const db = app.get('db')
const saveUsersToDB = (done) => {
db.User.bulkCreate(users)
.then(() => (done))
}
module.exports = {saveUsersToDB};
My app.test.js file:
.......
const expect = require('expect')
const request = require('supertest')
const {saveUsersToDB} = require('./seed/seed');
before(saveUsersToDB)
When I run the test below is the error I get:
Express listening on port 3000!
1) "before all" hook: saveUsersToDB
0 passing (2s)
1 failing
1) "before all" hook: saveUsersToDB:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
npm ERR! Test failed. See above for more details.
I thought returning .then(() => (done)) was enough? What am I doing wrong?
By default, Mocha tests have a 2 second timeout (which means that the test needs to be completed in 2 seconds).
You can increase it (in milliseconds) as follows:
this.timeout(5000); // this test can take up to 5 seconds
https://mochajs.org/#timeouts
Because (done) will actually return the function instead of invoking it. In order to call done, you need to write it this way.
.then(() => done())
However, I don't recommend using done along with promises. You just simply need to return the promise then mocha will handle it automatically.
const saveUsersToDB = () => db.User.bulkCreate(users)
I had the same isue. This error promps because the 2 seconds timeout, so if your test needs to connect to ddbb it will most provably surpas it.
What I did was to separate all my tests that needed somme kind of connection to external resources into my integration tests folder and then added the next flag in my package.json test script:
"int-test": "mocha --timeout 15000 tests/integration/**/*.test.js --compilers js:babel-register "
Follow this link for other ways to increase the timeout: mocha timout

Categories