cucumber js execution - ELIFECYLE ERR - node.js

I'm new to JS and trying cucumber js for the first time
This is how my step defn looks like:
Pseudocodes
Given("I launch Google.com", async (){
await Launch.launchGoogle():
})
When("I enter search text cucumber js", async (){
await Launch.searchCucumber():
})
This is how my Launch.js looks like:
module.exports launchGoogle= async function() {
await driver.get("www.google.com"):
}
module.exports searchCucumber = async function(){
await driver.findElement(By.name("q")).sendKeys("cucumber");
}
In this case, when I run the feature with 2 steps, I get ELIFECYCLE ERR at the end of first step.
When I remove the await in the step definitions, it runs fine. But, the console displays as 2 steps passed even before the chrome browser is launched. That is, it fires the Given and When steps and shows the result even as the code in Launch.js is still executing.
Pls help how to solve this?

I just figured out that the default step timeout is 5000ms. Since, launching the browser and hitting the URL was taking more than that, it was failing. i just increased the step timeout to 30000ms and it works fine.

Related

Firebase cloud function execution not ending

I have firebase project that has few cloud functions. Some of them sends push notifications to the users. Before deploying any function, I develop it using the nodeJS on my local environment with standalone nodejs project.
However today I noticed that the function execution gets stuck after I try to send a push notification to even a single user. I mean to say the cursor does not return after I hit the node test.js and the execution never stops. I need to do ctrl + z in order to end the execution. However I get the push notification.
My code:
async function sendTest() {
await admin.messaging().sendToDevice(token, payload);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
}
The following is also a similar code but it also doesn't end the execution even after printing the debug. statement.
async function sendTest() {
var notificationPersonalPromises = []
notificationPersonalPromises.push(admin.messaging().sendToDevice(token, payload));
await Promise.all(notificationPersonalPromises);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
}
In both the above cases, I get the notification in couple of seconds and the debug gets printed instantly. If I comment out the push notification code then everything works fine. Please help...
The following image shows how the functions never ends the cursor keeps waiting...
Thanks
Make sure that your cloud function have a retunr. Even if you don't return anything. You can also return your last promise like:
async function sendTest() {
return admin.messaging().sendToDevice(token, payload);
}
or just an empty return like here:
async function sendTest() {
await admin.messaging().sendToDevice(token, payload);
console.debug('Message Sent'); // this line gets printed instantly but execution continues
return
}

Is there a way to override "tab closing" in puppeteer cluster?

Puppeteer cluster closing tabs before I can take screenshot.
I am using puppeteer cluster with maxConcurrency 8. I need to take a screenshot after each page loads[Approx. 20000 urls]. Page.screenshot is not useful for me. My screenshot should include URL bar and desktop. Its basically like a full desktop screenshot. So I am using ImageMagick for taking a screenshot, (and xvfb for multiple screen management)
The problem is:
sometimes, screenshot is taken before switching to the right tab.
blank screenshot, coz current tab is closed, and tab which is not yet loaded came to front.
sometimes, error is thrown as screenshot couldnt be taken, because all the tabs were closed.
What I am doing is: when each page loads, I call page.bringToFront and spawn a child_process, which takes screenshot of the desktop using image magic import command.
cluster.queue(postUrl.href); //for adding urls to queue
await page.waitForNavigation(); // Wait for page to load before screenshot
//taking screenshot
const { spawnSync} = require('child_process');
const child = spawnSync('import', [ '-window', 'root', path]);
Dont want to setup waittime after page load, nodejs ImageMagick didnt work, and promise also didnt seem to work.
I do not want the puppeteer to close tab on its own. Instead, can it give callback event once page is loaded, wait for the callback function to be executed and returned and then the tab is closed??
As soon as the Promise of the cluster.task function is resolved, the page will be closed:
await cluster.task(async ({ page, data }) => {
// when this function is done, the page will be closed
});
To keep the page open you can await another Promise at the end before closing:
await cluster.task(async ({ page, data }) => {
// ...
await new Promise(resolve => {
// more code...
// call resolve() when you are done
});
});
Calling the resolve() function at the end will resolve the last Promise and therefore also resolve the whole async function. Therefore, it will close the page. Keep in mind that you want to increase the timeout value to something greater than 30 (default) if necessary when launching the cluster:
const cluster = await Cluster.launch({
// ...
timeout: 120000 // 2 minutes
});

MongoDB won't update with testcafe tests

Im using testcafe for GUI tests. I'm running the node server in the background and then start testing. When I'm navigating though the GUI with testcafe API it all works great, but when I'm trying to call a function that changes the db (hard coded in the test) the database isn't effected at all.
Here is my code:
fixture('Permissions')
.page('https://localhost');
test('go to permissions', async browser => {
await onlineFormsController.createOnlineFrom("OMRI",'NEWFORM',async ()=>{
await browser.click('#editUsersTree');
await browser.click('#loadDefaultTree');
await browser.wait(500);
await browser.pressKey('enter');
await browser.wait(500);
await browser.pressKey('enter');
await browser.click('#saveTree');
await browser.pressKey('enter');
await browser.navigateTo('https://localhost/Home');
await browser.wait(5000);
});
});
The function onlineFormsController.createOnlineFrom should create new form in my database, but nothing happened. It's working good separately form the testcafe test (tested it with mocha and it works great), but when I'm running the test with testcafe it's like this line is ignored or have no effects at all.
Any ideas what causing this problem?
TestCafe should not interfere with MongoDB work.  
I recommend you the following: 
ensure that the createOnlineFrom returns a Promise object;
do not pass function with test actions as a parameter. Since the createOnlineFrom returns a Promise object, you can organize your code in a more readable way:
test('go to permissions', async browser => {
await onlineFormsController.createOnlineFrom("OMRI",'NEWFORM');
await browser.click('#editUsersTree');
});
If these recommendations do not help, please provide the full code of your createOnlineFrom function.

Why does the selenium function elementLocated in node.js throw an error only on Jenkins?

I'm using the function driver.wait(until.elementLocated()) below, written with node.js, as an explicit wait on my Selenium tests to ensure that the pages in my test load properly. When I run the tests from my local CLI they work perfectly, headlessly and with GUI.
const loadMyPage = {
loadThePage: async function(driver) {
try {
await driver.wait(
until.elementLocated(
By.css("div.radio-select span:nth-child(7)")
),
20000
);
} catch (e) {
console.trace(loadMyPage.loadThePage);
throw e;
}
}
However, when I run the tests in Jenkins headlessly I receive the following error every time I use the function elementLocated().
TypeError: Wait condition must be a promise-like object, function, or a Condition object[0m[90m
at Driver.wait (node_modules/selenium-webdriver/lib/webdriver.js:928:13)
at Object.loadMyPage (foobar-tests/page.js:35:20)
at Context.<anonymous> (foobar-tests/foobar.test.js:32:30)
at <anonymous>
Is there anything specific that could cause this error in Jenkins? I have managed to narrow it down to this specific function, elementLocated().
I was able to find a workaround for my issue, however it appears that there is a larger issue at play with selenium. More information on the core issue can be found at https://github.com/SeleniumHQ/selenium/issues/5560.
I updated my explicit wait by passing an additional async function, and this cleared up the problem entirely in Jenkins. Example is below.
loadMyPage: async () => {
//The second async is necessary to run explicit wait functions like the one below.
//This issue is specific to selenium, more information can be found at https://github.com/SeleniumHQ/selenium/issues/5560.
loadThePage: async () {
try {
async driver =>
await driver.wait(
until.elementLocated(
By.css("div.radio-select span:nth-child(7)")
),
10000
);
} catch (e) {
console.trace(loadMyPage.loadThePage);
throw e;
}
}

selenium-webdriver in nodejs sample not returning current title

I was working through the selenium web-driver example and it didn't work. Several months ago it worked just fine so I am wondering if I am doing something wrong or if the testing methods have changed.
var assert = require('assert'),
test = require('selenium-webdriver/testing'),
webdriver = require('selenium-webdriver');
var By = webdriver.By;
test.describe('Google Search', function() {
test.it('should work', function(done) {
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get("http://www.google.com");
driver.findElement(By.name("q")).sendKeys("webdriver");
driver.findElement(By.name("btnG")).click();
driver.getTitle().then(function(title) {
assert.equal("webdriver - Google Search", title);
done();
});
driver.quit();
});
});
The output is:
AssertionError: "webdriver - Google Search" == "Google"
Expected :"Google"
Actual :"webdriver - Google Search"
This tells me that the page has not updated yet but I am not sure why. The example appears here: https://code.google.com/p/selenium/wiki/WebDriverJs#Getting_Started
Selenium version from package.json: 2.39.0
Update
I should have also stated that the test is being run through Mocha. Is Mocha the culprit? When I tried this last time it was using Jasmine.
Straight from the example in the documentation, use wait:
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
Why do you need to use wait? Because the Google page works asynchronously. After you enter the keys, it may take a bit of time before the server sends a response and the page is updated.
You should also remove done. While in general you need it for asynchronous tests, it seems the sequencer that comes with this incarnation of Selenium's webdriver will block on quit until all actions are performed. This example in the documentation does not use it.
Also, if you wonder why there is no assertion: you'll know your test has failed if you get a timeout exception when the timeout has expired.

Resources