Description
I’m currently facing an issue where a modal window pops up when there’s a record validation error, and I need to close it programmatically using Puppeteer.
Problem
Despite my efforts to investigate the HTML structure extensively, I have not been able to resolve the issue of closing this modal. The continuation of my automated processing is possible even with the modal open, but this leads to a timeout on another process in my script that waits for the modal to close before it proceeds to the next record. This timeout is crucial because it ensures that an important page element is loaded. Without it, my code becomes error-prone, and after trying numerous wait strategies, I found this timeout to be the most effective.
Modal HTML
Here’s the HTML snippet of the modal:
<div style="width: 400px; max-height: 530px; min-height: 250px; display: block;">
<h2 class="title_modal">Validation Error</h2>
<div class="col-xs-12"><h2 class="title_modal">Invalid ID</h2></div>
<div class="col-xs-4 col-xs-offset-4"><button class="primary">OK</button></div>
<span class="closeButton" id="modal_close_button"><i class="icon-close"></i></span>
</div>
Current Attempt
My current implementation for closing the modal is as follows:
const closeModalIfPresent = async (page) => {
const validationError = await page.evaluate(() => {
const modalHeader = document.querySelector('.title_modal');
if (modalHeader && modalHeader.textContent.includes('Validation Error')) {
const closeBtn = document.querySelector('.closeButton');
if (closeBtn) {
closeBtn.click();
return true;
}
}
return false;
});
if (validationError) {
console.log('Validation error modal closed.');
await new Promise(resolve => setTimeout(resolve, 100));
}
return validationError;
};
Method Invocation
This method gets called here:
const executePuppeteerScript = async (path, user, pass) => {
// Puppeteer setup...
await closeNewSession(page, user, pass);
const dataEntries = await readAndProcessFile(path);
for (const group of dataEntries) {
for (const entry of group) {
console.log(`Now processing: ${entry.id}`);
if (await checkForCustomerError(page)) continue;
await searchAndProceed(page, entry.id);
await new Promise(resolve => setTimeout(resolve, 200));
// Modal handling logic here
// if (await closeModalIfPresent(page)) continue;
}
}
};
Additional Notes
I’ve tried invoking the modal handling function before my search logic, but I still can’t get the modal to close.
Errors Encountered
When the modal stays open, I receive a timeout error like this:
Error getting data: TimeoutError: Waiting for selector failed: Waiting failed: 15000ms exceeded
If anyone knows how to successfully close the modal or can provide insights into adjusting my logic to re-attempt the entry processing, I would greatly appreciate it. I’ve only recently started using Node.js after struggling with the same task in C#, which was not only slower but also more complicated.
Thanks for taking the time to read this detailed query. Would it be better for future posts to keep them concise or is it more beneficial to provide comprehensive details?