linkedin webdriver | | Cell 1 | Search

The loginLinkedIn function logs a user into LinkedIn using the enterLinkedIn function, which retrieves login credentials from a hardcoded JSON file and uses Selenium to fill in the login form. The loginLinkedIn function does not check if the login was successful, it only checks if the user is logged in, and the enterLinkedIn function does not handle errors robustly.

Run example

npm run import -- "login linkedin"

login linkedin


const getClient = importer.import("selenium client")
const { Builder, Browser, By, Key, until } = require('selenium-webdriver')

const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const PASSWORDS_FILE = path.join(PROFILE_PATH, '.credentials', 'brian.json');

async function enterLinkedIn(driver) {
  console.log('LinkedIn: Sign in required');

  var credentials = require(PASSWORDS_FILE)

  let loginButton = await driver.findElement(By.css('a[href*="/login"]'))
  if(!loginButton.error) {
    try {
      await loginButton.click()
    } catch (e) {}
    await new Promise(resolve => setTimeout(resolve, 2000))
  }

  //let body = await driver.findElement(By.css('body'))
  await driver.wait(until.elementLocated(By.css('.login-form, [type="submit"]')), 10000);
  let submit = await driver.findElement(By.css('.login-form, [type="submit"]'))

  let login = await driver.findElement(By.css('input[name*="session_key"]'))
  
  await driver.executeScript('arguments[0].click();', login)
  await driver.actions().sendKeys(credentials.username).perform()

  await new Promise(resolve => setTimeout(resolve, 1000))

  //await pass.sendKeys(credentials.username)
  //await driver.executeScript('arguments[0].value="' + credentials.username + '";', login)
  
  console.log('LinkedIn: Require password')

  let pass = await driver.findElement(By.css('input[name*="session_password"]'))
  await pass.click()
  await pass.sendKeys(credentials.password)

  await submit.click()

  await new Promise(resolve => setTimeout(resolve, 3000))

  let loginStill, loginStill2
  try {
    loginStill = await driver.findElement(By.css('#captcha-internal'))
  } catch (e) {}
  try {
    loginStill2 = await driver.findElement(By.css('input[name*="session_password"]'))
  } catch (e) {}
  if(loginStill || loginStill2) {
    throw new Error('captcha')
  }
}

async function loginLinkedIn(driver) {
  if(!driver) {
    driver = await getClient();
  }

  try {
    let url = await driver.getCurrentUrl()
    let loggedIn = url.indexOf('linkedin') > -1 && url.indexOf('login') == -1
                && url.indexOf('authwall') == -1

    if(loggedIn) {
      if(await driver.findElement(By.xpath('iframe.authentication-iframe'))) {
        await driver.frame((await driver.element('iframe.authentication-iframe')).value)
        await enterLinkedIn()
        await frame()
      }
    } else {
      //await driver.executeScript('window.location="https://www.linkedin.com/"', [])
      //await driver.url('https://www.linkedin.com/')
      await driver.get('https://www.linkedin.com/')
      let loginLink, loginLink2
      try {
        loginLink = await driver.findElement(By.xpath('//a[text()[contains(.,"Forgot password?")]]'))
      } catch (e) {}
      try {
        loginLink2 = await driver.findElement(By.xpath('//a[text()[contains(.,"Join now")]]'))
      } catch (e) {}

      if(loginLink || loginLink2) {
        await enterLinkedIn(driver)
      }
    }
  } catch (e) {
    driver.quit()

    throw e
  }

  return driver
}

module.exports = loginLinkedIn

What the code could have been:

const { Builder, Browser, By, Key, until } = require('selenium-webdriver');
const { Client } = require('webdriverio');

const PASSWORDS_FILE = process.env.HOME
 ? `${process.env.HOME}/.credentials/brian.json`
  : process.env.HOMEPATH
 ? `${process.env.HOMEPATH}/.credentials/brian.json`
  : process.env.USERPROFILE
 ? `${process.env.USERPROFILE}/.credentials/brian.json`
  : null;

async function enterLinkedIn(driver) {
  try {
    // Wait for the login button to be clickable
    await driver.wait(until.elementClickable(By.css('a[href*="/login"]')), 10000);
    const loginButton = await driver.findElement(By.css('a[href*="/login"]'));
    await loginButton.click();

    // Wait for the login form to be visible
    await driver.wait(until.elementLocated(By.css('.login-form, [type="submit"]')), 10000);
  } catch (error) {
    // If the login button is not found, try to proceed with the login
  }

  const loginForm = await driver.findElement(By.css('.login-form, [type="submit"]'));
  const loginInput = await driver.findElement(By.css('input[name*="session_key"]'));
  await driver.executeScript('arguments[0].click();', loginInput);
  await loginInput.sendKeys(process.env.BRIAN_USERNAME || require(PASSWORDS_FILE).username);

  await driver.sleep(1000); // Wait for 1 second

  const passwordInput = await driver.findElement(By.css('input[name*="session_password"]'));
  await passwordInput.click();
  await passwordInput.sendKeys(process.env.BRIAN_PASSWORD || require(PASSWORDS_FILE).password);

  const submitButton = await loginForm.findElement(By.css('button[type="submit"]'));
  await submitButton.click();

  await driver.sleep(3000); // Wait for 3 seconds

  try {
    const captcha = await driver.findElement(By.css('#captcha-internal'));
    throw new Error('captcha');
  } catch (error) {}
}

async function loginLinkedIn(client = null) {
  if (!client) {
    client = await Client.default();
  }

  try {
    const url = await client.getUrl();
    const loggedIn = url.indexOf('linkedin') > -1 && url.indexOf('login') == -1 && url.indexOf('authwall') == -1;
    if (loggedIn) {
      // If already logged in, check if we need to handle the authentication iframe
      if (await client.findElement(By.css('iframe.authentication-iframe'))) {
        await client.switchToFrame(await client.element('iframe.authentication-iframe'));
        await enterLinkedIn();
      } else {
        // If not in the iframe, we're already logged in
        return client;
      }
    } else {
      // If not logged in, navigate to the login page
      await client.get('https://www.linkedin.com/');
      try {
        await client.findElement(By.xpath('//a[text()[contains(.,"Forgot password?")]]'));
      } catch (error) {}
      try {
        await client.findElement(By.xpath('//a[text()[contains(.,"Join now")]]'));
      } catch (error) {}
      await enterLinkedIn(client);
    }
  } catch (error) {
    client.end();

    throw error;
  }

  return client;
}

module.exports = loginLinkedIn;

Code Breakdown

Importing Dependencies

const getClient = importer.import('selenium client')
const { Builder, Browser, By, Key, until } = require('selenium-webdriver')

Environment Variables and File Path

const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const PASSWORDS_FILE = path.join(PROFILE_PATH, '.credentials', 'brian.json');

enterLinkedIn Function

async function enterLinkedIn(driver) {
 ...
}

loginLinkedIn Function

async function loginLinkedIn(driver) {
 ...
}

Notes