Search code examples
node.jsplaywright

Twilio One Time Password with Playwright: Node.js (automating login with github's 2FA)


I'm trying to automate Github's two factor authentication with Playwright.

line 47 is where I'm stuck (after // get OTP ..) const element = await page.waitforselector(() => {

is there an workaround for this? Any help here is appreciated. This code retrieves github's 2 factor auth code via twilio's received messages and then should input it at the 'otp' selector.

const accountSid = 'examplesid';
const authToken = 'exampleauthtoken';
const client = require('twilio')(accountSid, authToken);
 


const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    headless: false
  });
  const context = await browser.newContext();

  // Open new page
  const page = await context.newPage();

  // Go to https://github.com/login
  await page.goto('https://github.com/login');

  // Click input[name="login"]
  await page.click('input[name="login"]');

  // Fill input[name="login"]
  await page.fill('input[name="login"]', 'usernameexample');


  // Press Tab
  await page.press('input[name="login"]', 'Tab');

  // Fill input[name="password"]
  await page.fill('input[name="password"]', 'passwordexample*');

  // Press Enter
  await page.press('input[name="password"]', 'Enter');
  // assert.equal(page.url(), 'https://github.com/sessions/two-factor');


  // Click [placeholder="6-digit code"]
    await page.click('[placeholder="6-digit code"]');

  // get OTP ...

   
     
  const element = await page.evaluate(() => {
    return new Promise((resolve, reject) => {
      try {
        client.messages.list({limit: 1 })
        .then((messages) => 
          messages.forEach((m) => {
            console.log(m.body);
            resolve(m.body);
         })
        );
  
      } catch (error) {
        reject (error);
      }
    }); 
   });
 
   

  // ---------------------
  await context.close();
  await browser.close();
 })();

error I get:

unhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:23523) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Solution

  • Resolved. Removed Const element and the promise for:

      // get OTP (one time password)
      const messages = await client.messages.list({limit: 1});
      const number = messages[0].body.substr(0,6);
    
      //Fill OTP
      await page.fill('input[name="otp"]', number); 
      await page.press('input[name="otp"]', 'Enter');