S..
S..

Reputation: 335

Puppeteer Error: Node is either not visible or not an HTMLElement but it is

I tried all the suggestions in this thread but none of them worked. The strangest thing is that when I try to search for the element in chrome console by xpath I get a result

enter image description here

puppeteer also manages to find the <select> and exact <option> but fails to click it, here is my code to reproduce the behavior:

const browser = await puppeteer.launch({ 
                    defaultViewport: { 'width' : 1920, 'height' : 1080 },
                    executablePath: exec_path,
                    args: ['--disable-web-security', '--ignore-certificate-errors']
                });
                const page = await browser.newPage();
                
                await page.goto("https://releases.footshop.com/nike-w-dunk-low-8XCQ7nsB6RTO0K-RInj-"), { 
                    waitUntil: 'load', 
                    timeout: 0 
                }; 

                //part 1

                await page.click('span[class="default-text__21bVM"]');
                
                let size = 9;
                
                const xp = `//div[contains(@class, "col-3") and text()="${size}"]`;
                await page.waitForXPath(xp);
                const [sizeButton] = await page.$x(xp);
                await sizeButton.click();


                await page.click('span[class="text__1S19c"]');
                
                //part 2
                   
                await page.type("input[name='email']", "[email protected]");  
                await page.type("input[name='phone']", "73246732812");

                const xp2 = `//button[contains(@class, "continue-button__1RtsS")]`;
                await page.waitForXPath(xp2);
                const [continueButton] = await page.$x(xp2);
                await continueButton.click();

                //part 3

                let gender = "male"
                if(gender === "male") { 
                    await page.click('input[value="Mr"]')
                }
                else if(gender === "female") {
                    await page.click('input[value="Mrs"]')
                }

                await page.type("input[name='firstName']", "name");
                await page.type("input[name='lastName']", "lastname");
                await page.type("input[name='instagramUsername']", "instagramname");

                //birthday
                let birthday = "05/05/1997";
                //separate
                let dates = birthday.split("/")
                
                //Day
                const xp3 = `//button[contains(@class, "dropdown-toggle btn btn-primary") and text()="Day"]`;
                await page.waitForXPath(xp3);
                const [dayButton] = await page.$x(xp3);
                await dayButton.click();
                

                //Specific day 
                const xp4 = `//div[@class='dropdown-menu show']/button[contains(., '${dates[0]}')]`;
                await page.waitForXPath(xp4);
                const [specificDaybutton] = await page.$x(xp4);
                await specificDaybutton.click(); 
                

                //Month
                const xp5 = `//button[contains(@class, "dropdown-toggle btn btn-primary") and text()="Month"]`;
                await page.waitForXPath(xp5);
                const [monthButton] = await page.$x(xp5);
                await monthButton.click();
                

                //Specific Month
                const xp6 = `//div[@class='dropdown-menu show']/button[contains(., '${dates[1]}')]`;
                await page.waitForXPath(xp6);
                const [specificMonthbutton] = await page.$x(xp6);
                await specificMonthbutton.click(); 
                

                //Year
                const xp7 = `//button[contains(@class, "dropdown-toggle btn btn-primary") and text()="Year"]`;
                await page.waitForXPath(xp7);
                const [yearButton] = await page.$x(xp7);
                await yearButton.click();
                

                //Specific Year
                const xp8 = `//div[@class='dropdown-menu show']/button[contains(., '${dates[2]}')]`;
                await page.waitForXPath(xp8);
                const [specificYearbutton] = await page.$x(xp8);
                await specificYearbutton.click(); 
                
                //Continue
                const xp9 = `//button[contains(@class, "continue-button__1RtsS")]`;
                await page.waitForXPath(xp9);
                const [continueButton2] = await page.$x(xp9);
                await continueButton2.click();

                //part 4
                
    
                //Country
                // const xp12 = `//select[@name="country"]`;
                // await page.waitForXPath(xp12);
                // const [countryButton] = await page.$x(xp12);
                // await countryButton.click();
                
                // await page.screenshot({ path: 'ftshp country list' + ii + '.png'});

                //Specific Country
                //await page.select('select[name="country"]', "Austria");
                
                const xp13 = `//select[@name='country']/option[text()='Austria']`;
                await page.waitForXPath(xp13);
                const [specificCountryoption] = await page.$x(xp13);
                // await specificCountryoption.evaluate(btn => {
                //     btn.dispatchEvent(new Event("mousedown"));
                // });
                // await specificCountryoption.evaluate(b => b.click());
                await specificCountryoption.click();  // error here
                //await page.evaluate(()=>document.querySelector(specificCountryoption).click())
                

                //further code to follow

In the code I first tried to open up the country <select> alone and then select a specific option separately, but then just decided to do both open select element and select a specific option in one xpath, there are multiple attempts at this, none of which worked for me, some do not throw errors but also do not select a country and just continue the script without it.

I got the furthest with await specificCountryoption.click(); since it finds the exact option but can't click / select it.

The whole process needs to be replicated in order to get to the country selection tab unfortunatelly, thanks for any suggestions on how to select a specific option.

Upvotes: 2

Views: 430

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167436

If you have a handle to the HTML select element there is a method select you can call: https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#elementhandleselectvalues.

Based on that, countryButton.select('AT') might select the option with the value AT for Austria in that country select box.

Upvotes: 1

Related Questions