I’m utilizing Puppeteer with NodeJS to perform testing on a particular website. While everything functions as expected in most scenarios, I occasionally encounter the following error:
Error: Node is not visible or not an HTMLElement
The code below attempts to access links that, in both instances, are located off-screen.
Although the initial link clicks successfully, the second link results in an error.
What distinguishes the two links, given that both are off-screen?
I would appreciate any assistance you can provide. Thank you!
Sample Code
const puppeteer = require('puppeteer');
const targetPage = 'https://example.com/path';
const linkSelectors = [
'div[id$="-abc123"] article a',
'div[id$="-xyz456"] article a'
];
(async () => {
let selectedLink, linkHandles, specificLink;
const viewportWidth = 1024, viewportHeight = 1600;
const browserInstance = await puppeteer.launch({
headless: false,
defaultViewport: { width: viewportWidth, height: viewportHeight }
});
const pageInstance = await browserInstance.newPage();
await pageInstance.setViewport({ width: viewportWidth, height: viewportHeight });
pageInstance.setUserAgent('UA-TEST');
// Open the initial page
let response = await pageInstance.goto(targetPage, { waitUntil: 'domcontentloaded' });
// Attempt click on first link - successful
selectedLink = linkSelectors[0];
await pageInstance.waitForSelector(selectedLink);
linkHandles = await pageInstance.$$(selectedLink);
specificLink = linkHandles[12];
console.log('Clicking on: ', await pageInstance.evaluate(elem => elem.href, specificLink));
await specificLink.click(); // Success
// Attempt click on second link - fails
selectedLink = linkSelectors[1];
await pageInstance.waitForSelector(selectedLink);
linkHandles = await pageInstance.$$(selectedLink);
specificLink = linkHandles[12];
console.log('Clicking on: ', await pageInstance.evaluate(elem => elem.href, specificLink));
await specificLink.click(); // Error: Node is not visible or not an HTMLElement
})();
I am trying to replicate the experience of a genuine user navigating the site, which is why I opt for the .click()
method instead of .goto()
, since the <a>
tags have associated onclick
event handlers.
Hello HappyDancer99,
Your issue with the "Error: Node is not visible or not an HTMLElement" could stem from several factors related to the page rendering and its elements. Let's explore some additional approaches beyond the solution provided by Hazel_27Yoga:
- Timeout Considerations: Ensure that the page and all dynamic contents have completely loaded before interacting with them. Consider increasing the timeout for
waitForSelector
, or explicitly waiting for the element's visibility using:
await pageInstance.waitForFunction(selector => {
const element = document.querySelector(selector);
return element && window.getComputedStyle(element).visibility !== 'hidden';
}, {}, selectedLink);
- Element Evaluation: Beyond visibility issues, ensure the element is still in the DOM by evaluating its existence within the page lifecycle. You can use:
const isExist = await pageInstance.evaluate(sel => {
const el = document.querySelector(sel);
return el !== null;
}, selectedLink);
if (!isExist) {
console.log(‘Element does not exist in DOM.’);
}
This can help you identify if there’s any dynamic loading affecting the element’s presence.
- Event Listeners: Sometimes onclick handlers might have conditions for element state. Consider using the
pageInstance.evaluate()
method to verify and interact programmatically:
await pageInstance.evaluate(sel => {
const el = document.querySelector(sel);
if (el) el.click();
}, selectedLink);
This can directly simulate a click after applying checks for the element state.
By applying these strategies, you might identify underlying causes that prevent Interaction. These tailored steps can aid better testing by ensuring everything is appropriately loaded and visible before actions are taken. Let me know how it goes or if further assistance is needed!
Hello HappyDancer99,
The error you're facing typically arises when elements are out of view or their visibility is affected by CSS properties. Here’s a streamlined approach to tackle this efficiently:
- Scroll the Element into View: Ensure the element you're trying to interact with is visible on the screen. Use the following code to scroll the element into view before clicking:
await pageInstance.evaluate(elem => elem.scrollIntoView(), specificLink);
- Check CSS Properties: Verify that the element is not hidden by CSS properties like
display: none
or visibility: hidden
. Use this code snippet to perform a check:
const isElementVisible = await pageInstance.evaluate(elem => {
const style = window.getComputedStyle(elem);
return style.display !== 'none' && style.visibility !== 'hidden';
}, specificLink);
if (!isElementVisible) console.log('Element is not visible due to CSS properties.');
- Inspect the Page: Run the browser in non-headless mode (as you're doing) and visually inspect whether the element appears as expected. This ensures you're not missing any dynamic changes affecting element positioning or structure.
By applying these steps, you should be able to resolve the issue and execute your test successfully. If you encounter further complications, feel free to ask for more help!
Hi HappyDancer99,
The error you're encountering is often due to elements being out of view or affected by CSS properties that render them undetectable by Puppeteer. Here are some steps to resolve this issue efficiently:
- Scroll into View: Before clicking on an element, ensure it's visible in the viewport. Use:
await pageInstance.evaluate(elem => elem.scrollIntoView(), specificLink);
This will bring the element into view, ensuring it can be interacted with.
- Check Display and Visibility: Ensure the element is not hidden via CSS properties like
display: none
or visibility: hidden
. Use the page.evaluate()
function to inspect these properties. For example:
await pageInstance.evaluate(elem => {
const style = window.getComputedStyle(elem);
return style && style.display !== 'none' && style.visibility !== 'hidden';
}, specificLink);
- Debugging: Since you have a headless browser running, visually inspect to see if the link is indeed visible and in the expected position. Sometimes the page structure on different screens may change.
Give these steps a try to ensure your test runs smoothly. Let me know if you need further assistance!
Hey HappyDancer99,
For the error "Node is not visible or not an HTMLElement," try scrolling the element into view before clicking it. This ensures it's accessible for interaction:
await pageInstance.evaluate(elem => elem.scrollIntoView(), specificLink);
Check CSS properties too, like display
and visibility
, to ensure it's not hidden:
await pageInstance.evaluate(elem => {
const style = window.getComputedStyle(elem);
return style && style.display !== 'none' && style.visibility !== 'hidden';
}, specificLink);
This should help with the visibility issue!