1

I want to do input like the one in this picture

    const ele = $('#oauth_form > fieldset.sign-in > div > input[id="username_or_email"]')
if(ele.length> 0){
    ele[0].value = 'Halllooooo'
}

this output when i use javascript in browser console

Puppeteer

 async function main()  {

    const context = browser.defaultBrowserContext();
    context.overridePermissions("https://toolkity.com/twitter/free-twitter-followers", ["clipboard-read"]);

    const pages = await browser.pages();
    const page = pages[0];
    await page.setDefaultNavigationTimeout(0);
    await page.goto('https://toolkity.com/twitter/free-twitter-followers', {
        waitUntil: 'domcontentloaded'
    });

    await delay(2000)
    await page.waitForSelector('#twitterFollowersApp > div:nth-child(1) > div > div > div.card-body > form > div:nth-child(3) > a')
    await page.evaluate(() => document.querySelector('#twitterFollowersApp > div:nth-child(1) > div > div > div.card-body > form > div:nth-child(3) > a').click())

    await delay(5000)
    await page.waitForSelector('#username_or_email')
    const inputUser = await page.evaluate('#username_or_email')
    await inputUser.click({clickCount: 3})
    await page.keyboard.type('test')
}
main()

output = TimeoutError: Waiting for selector #username_or_email failed: Waiting failed: 30000ms exceeded

and i think maybe puppeteer is not working because there is 1 dynamic element.

before element

class="row user"

after input text

class="row user content"

this link in the photo above, click Get Pin Code On Twitter and you will get something like the photo above

  • [DevTools is different than Puppeteer](https://blog.appsignal.com/2023/02/08/puppeteer-in-nodejs-common-mistakes-to-avoid.html#assuming-browser-devtools-is-the-same-as-node). Many reasons could contribute to this. Please provide a [mcve]. Thanks. – ggorlen Feb 28 '23 at 20:00
  • 1
    @ggorlen sorry I fixed – Alma Muhamad Apriana Feb 28 '23 at 20:17

1 Answers1

1

The fundamental problem is that the href on that link isn't present initially. It's populated dynamically, so it needs to be blocked for:

const puppeteer = require("puppeteer"); // ^19.6.3

const url = "<Your URL>";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const xp = '//a[text()="Get Pin Code On Twitter"]';

  for (let tries = 0;; tries++) {
    const el = await page.waitForXPath(xp);

    if (await el.evaluate(e => !!e.getAttribute("href"))) {
      break;
    }
    else if (tries > 100) {
      throw Error("Tries exceeded waiting for href");
    }
  }

  const pageTarget = page.target();
  await (await page.waitForXPath(xp)).click();
  const newTarget = await browser.waitForTarget(
    target => target.opener() === pageTarget
  );
  const newPage = await newTarget.page();
  const userInput = await newPage.waitForSelector("#username_or_email");
  await userInput.type("test");
  await newPage.screenshot({path: "test.png"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

Beyond that, here's a rundown of a few issues in your code:

ggorlen
  • 44,755
  • 7
  • 76
  • 106