Node.js: close browser if its open using Pupeteer - javascript

I am doing processing using Puppeteer and I am closing the browser like using browser.close() for example something like this
const browser = await puppeteer.launch({
headless: true,
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
});
try {
// more processing
browser.close();
// more processing
} catch(err) {
console.log(err);
browser.close();
}
I am using browser.close(); in catch block, but sometimes the browser.close() is already executed in try block when the exception occurs.
I want to know if there is a way to check if browser.open? and issue browser.close() only in that case.
Any help in this would be really great. Thanks.

Take a look about try...catch
You should add finally block and add there browser close :)
The finally-block contains statements to execute after the try-block and catch-block(s) execute, but before the statements following the try...catch...finally-block. Note that the finally-block executes regardless of whether an exception is thrown. Also, if an exception is thrown, the statements in the finally-block execute even if no catch-block handles the exception.
Edit 1
After understanding that issue is detecting if browser is closed I edit and input solution for that problem puppeteer : how check if browser is still open and working

Related

(No debugger available, can not send 'variables' )error [duplicate]

I'm getting started with pupeteer and node and using vscode in win 10. I'm trying to log into a site and scrape a table. So far I have:
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
var page = await browser.newPage();
await page.goto('thesite.com/login/');
await page.click(USERNAME_SELECTOR);
await page.keyboard.type(CREDS.username);
await page.click(PASSWORD_SELECTOR);
await page.keyboard.type(CREDS.password);
await page.click(BUTTON_SELECTOR);
await page.waitForNavigation();
const TABLE_ROW_SELECTOR = '.gv-container.gv-container-133 > table > tbody';
await page.waitForSelector(TABLE_ROW_SELECTOR);
await page.waitForSelector(TABLE_ROW_SELECTOR);
await page.screenshot({ path: 'example.png' });
const data = await page.evaluate(SELECTOR => document.querySelectorAll(SELECTOR), TABLE_ROW_SELECTOR);
await browser.close();
})();
This is mostly working. however in my console I see a list of objects but as far as I can tell no values. Heres the fiest object:
0:Object {}
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
__defineGetter__:function __defineGetter__() { … }
__defineSetter__:function __defineSetter__() { … }
__lookupGetter__:function __lookupGetter__() { … }
__lookupSetter__:function __lookupSetter__() { … }
constructor:function Object() { … }
hasOwnProperty:function hasOwnProperty() { … }
No debug adapter, can not send 'variables'
isPrototypeOf:function isPrototypeOf() { … }
No debug adapter, can not send 'variables'
What does " No debug adapter, can not send 'variables'" mean?
edit:
I updated to the latest vscode and checked that all extensions were updated. Now when I run LAUNCH PROGRAM
E:\nodejs\node.exe --inspect-brk=27108 index.js
Debugger listening on ws://127.0.0.1:27108/e5928c71-370c- 4111-9ec3-77bb2cd85075
For help, see: https://nodejs.org/en/docs/inspector
(node:12844) ExperimentalWarning: The fs.promises API is experimental
warning.js:18
Array(25) [ElementHandle, ElementHandle, ElementHandle, ElementHandle, ElementHandle, ElementHandle, ElementHandle, ElementHandle, …]
index.js:64
length:25
__proto__:Array(0) [, …]
concat:function concat() { … }
[[Scopes]]:Scopes[0]
arguments:TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
Any idea what this means?
I had this issue when trying to use the integratedConsole rather than integratedTerminal or externalTerminal as part of my Node configuration within launch.json:
Setting it back to:
"console": "integratedTerminal"
Fixed it. Only took an hour to figure out. See docs for more information.
You can also try:
"outputCapture": "std"
in your launch.json
Here is reference on Github
The reason this happens is that the debugger stops after the code execution ends. Then there is no more debug adapter available to send the variables. What I did is add an extra line on the bottom of the code execution, and set a breakpoint on that. It isn't pretty, but it works.
I had the same problem, but that was me who caused this error ...
I have a conditional breakpoint defined in some scope of code, I have tried to use it in another conditional breakpoint but in a different scope.
The variable used on this condition was not found in the new scope. that's why the debugger can not start and gives us this error.
When I figured out, I used the defined variables on the scope to get the condition work properly.
Not a very big deal, but I hope this can help someone
I had a similar problem when the JavaScript script was erroring-out because of a missing async keyword on an await-using function during an initial evaluation step before normal execution and the vscode debugger was not catching the error in a meaningful error reporting context before the execution context exited.

How to optionally handle a modal with Playwright?

Sometimes there is a modal window that pops up. I have this try catch to handle it and it works in headless mode. However, when I'm in VSCode, it stops when the error is thrown.
await test.step('Optionally click continue', async () => {
try {
page.getByRole('cell', { name: 'Continue' }).click({ timeout: 10000 });
} catch (error) {
}
});
Error Screenshot
Is there a playwright preferred way to handle this that doesn't throw an exception? The playwright extension stops on exceptions to help debug. In this case, I would prefer a way to optionally handle a button without an exception being thrown.
You can use:
if page.isVisible('role=cell[name="Continue"i]') {
//Whatever
}

Node.js catch statement return does not stop executing

I'm trying to create a discord bot with the help of node.js
In which I need to call a function that may return discord API errors I handle them like this
interaction.user.send("Hi")
.catch(() => {return interaction.reply("...");
console.log("shouldnt run if an error accured")
However whenever that API error accurse the return statement unlike normally does not stop the code execution.
How do I stop the console.log statement in this code from executing when the exception accurse ?
the js is asynchronous so it puts the request of API in execution queue(not wait for response from api) and continue its execution that's why your console statement is running even if the error occurs.
interaction.user.send("Hi")
.then(() => {
// do whatever you want when it succeed
})
.catch((error) => {
// handle error
});
you can also checkout async await for the same.
As #ParthPatel indicates, interation.user.send() is returning a Promise which may not be rejected immediately upon error. Statements such as your console.log() will run before an error has a chance to occur and be caught.
However, these days there is the async await syntax you can use, which may help you simplify your code a bit depending on what you're trying to do.
try {
await interaction.user.send("Hi");
console.log('Shouldn\'t run if error occurred.');
} catch(e) {
interaction.reply('...');
}
Note that you can only use await inside of an async function, declared like this:
async function doSomething() {
// Do something here...
}
You can find more information here: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

Handling valid modal dismissals and true exceptions

In most Angular libraries (and specifically ng-boostrap) there is a way to open modals on the page that block the user from doing anything until they every "close" the modal or "dismiss" the modal. In ng-bootstrap it looks like this.
try {
let handle = this.nbgModal.open(...);
await handle.result;
// any code here won't run until after the modal is 'closed'
}catch(e){
// however, if the user 'dismisses' the modal then the catch block is ran
// so what happens in here if a real exception is thrown???
}
The response of the open(...) method allows you to use async/await keywords to wait for the modal to be interacted with by the user before proceeding to the rest of the code.
If the user "closes" the model, the Promise is resolved and we continue using some result from the modal possibly. However, if the user "dismisses" the modal then we will reject the Promise and the code in the catch block will run.
So now the final question... what happens when a true exception is thrown in any of the code in the try block above? In this example we would swallow the exception and the user/developer would never know since the console won't emit an error.
Use promises for modal like this has been so methign I've seen for years, so what is the expected solution for determining whether you are dealing with a valid business scenario (e.g. dismissal) vs. an exception that is throw due to a bug?
I have a solution to this but I feel like I would be fighting against these libraries to build another service that does ever reject unless theres a true exception. Am I missing somethign that should allow me to do this?
I wouldn't blame the developers of libs. Raising expectation on the promise rejection when using await seems doubtful as well.
try {
let handle = this.nbgModal.open(...);
handle.result
.then(result=>doSmgWithDialogResult(result))
.catch(()=>doSmgWhenDialogDIsmnissed());
} catch(e) {
// catch exceptions
}

NoSuchElementError: No element found using locator doesn't fail the protractor spec but it passes flawlessly

This is an automation framework using page object model. I use the async/await approach over promises. I am using TS, compiling it to JS (protractor) and then executing the scripts.
Page Object:
async addProjectDetails(): Promise<void> {
expect(await this.currentStep.getText()).toBe("Records"); //There is no element like this, which I know.
await this.projectTitle.sendKeys("Project Feb 1");
await this.projectDescription.sendKeys("Project Description");
}
Spec:
it('should create a project successfully', async () => {
try {
await dashboard.createNewProject();
await dashboard.addProjectDetails();
}
The page loads and the element doesn't exist. I get the error:
NoSuchElementError: No element found using locator: By(xpath, //custom-expandable-title[#class='not-completed active']//span[#class='child-title'])
However instead of failing the spec passes. Shouldn't it fail. Isn't this a false positive?
Errors raised in try wouldn't affect final result, they will stop execution of try block and start execution of catch block. If you want test to behave like this you have to move call of addProjectDetails away of try block.

Categories