skip to Main Content

I installed Puppeteer and want to query a selector to work on it.
But I have encountered a TypeError: selector.startsWith is not a function error.

I tried to fix it by changing core code by adding toString() but it didn’t work.

Here are the two expressions I’ve tried:

await page.$eval('#firstName', elem => elem.click());
await page.waitForSelector('#firstName');

Both did not work and created same error.

I also tried to install old puppeteer and node versions but its still same.
How can I solve this problem?

All error log information is:

file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/GetQueryHandler.js:51
                if (selector.startsWith(prefix)) {
                             ^

TypeError: selector.startsWith is not a function
    at getQueryHandlerAndSelector (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/GetQueryHandler.js:51:30)
    at CDPElementHandle.$ (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/ElementHandle.js:74:51)
    at IsolatedWorld.$ (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/IsolatedWorld.js:126:25)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async IsolatedWorld.focus (file:///C:/Users/User/Desktop/mail/node_modules/puppeteer-core/lib/esm/puppeteer/common/IsolatedWorld.js:186:24)
    at async file:///C:/Users/User/Desktop/mail/index.js:17:5

My full code example to produce same error is:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const context = await browser.createIncognitoBrowserContext();
  if (context) {
    const page = await browser.newPage();

    await page.goto('https://accounts.google.com/signup/v2/webcreateaccount?biz=false&cc=TR&dsh=S-519439412%3A1682412535258329&flowEntry=SignUp');
  
    // Set screen size
    await page.setViewport({width: 1080, height: 1024});
    //await page.$eval('#firstName', elem => elem.click());
    const username = await page.waitForSelector('#firstName');
    await page.focus(username)
    await page.keyboard.type('test54')
  }

})();

2

Answers


  1. You need to pass a string for the first argument of any function like page.focus(selector). The argument selector is the CSS or Puppeteer selector you want to take action on.

    In your code below, you’re passing an ElementHandle rather than a string:

    const username = await page.waitForSelector('#firstName');
    await page.focus(username);
    

    This throws because ElementHandles don’t have .startsWith methods.

    There are two possible solutions:

    const username = await page.waitForSelector('#firstName');
    await page.focus('#firstName'); // pass a string
    

    Or, since you already have the element handle:

    const username = await page.waitForSelector('#firstName');
    await username.focus(); // call .focus() on the ElementHandle
    

    For future vistors’ sake, here are some common calls to Puppeteer selector functions that also cause the same error:

    const puppeteer = require("puppeteer"); // ^19.11.1
    
    let browser;
    (async () => {
      browser = await puppeteer.launch({headless: "new"});
      const [page] = await browser.pages();
      await page.setContent("<p>hi</p>");
    
      /* any of the following lines throws */
    
      // ElementHandle
      const handle = await page.$("p");
      await page.focus(handle)
        .catch(err => console.error(err.message, "(handle)"));
    
      // Promise
      await page.focus(new Promise((res, rej) => {}))
        .catch(err => console.error(err.message, "(promise)"));
    
      // number
      await page.waitForSelector(42)
        .catch(err => console.error(err.message, "(number)"));
    
      // func
      await page.$$eval(() => {})
        .catch(err => console.error(err.message, "(func)"));
    
      // object
      await page.$eval({})
        .catch(err => console.error(err.message, "(object)"));
    
      // array
      await page.$(["#first-name"])
        .catch(err => console.error(err.message, "(array)"));
    
      // boolean
      await page.$$(true)
        .catch(err => console.error(err.message, "(boolean)"));
    
      // null
      await page.click(null)
        .catch(err => console.error(err.message, "(null)"));
    
      // undefined
      await page.$()
        .catch(err => console.error(err.message, "(undefined)"));
    })()
      .catch(err => console.error(err))
      .finally(() => browser?.close());
    

    Output:

    selector.startsWith is not a function (handle)
    selector.startsWith is not a function (promise)
    selector.startsWith is not a function (number)
    selector.startsWith is not a function (func)
    selector.startsWith is not a function (object)
    selector.startsWith is not a function (array)
    selector.startsWith is not a function (boolean)
    Cannot read properties of null (reading 'startsWith') (null)
    Cannot read properties of undefined (reading 'startsWith') (undefined)
    

    Puppeteer offers custom query selectors like "text/foobar" and "pierce/p". The API at the current time starts by optimistically checking for the presence of one of these prefixes using .startsWith, which is a property that only exists on strings.

    One way to avoid this error is to use TypeScript. Otherwise, check the Puppeteer docs for the method you’re trying to call to make sure you’re passing the appropriate type.


    Unrelated, but await browser.newPage(); should be await context.newPage(); if you want to use the context you created.

    Login or Signup to reply.
  2. You need to click the selector #firstName so just change

    await page.focus(username);
    

    to

    await username.click();
    

    that will solve the error, also if you want to use incognito, then

    const page = await browser.newPage();
    

    should be

    const page = await context.newPage();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search