This guide shows you how to automate web browsers using Selenium with JavaScript (Node.js). You’ll learn to write scripts that open pages, click buttons, fill forms, and extract data—all without a real user. This is useful for testing web apps, scraping repetitive tasks, or automating workflows. Before you start, you’ll need Node.js installed (v14 or later) and a code editor. We’ll use the official selenium-webdriver package, which works with Chrome, Firefox, and other browsers.
What You’ll Need
- Node.js (v14 or later) installed on your computer
- A code editor (VS Code, Sublime, etc.)
- A browser installed (Chrome, Firefox, or Edge)
- A terminal or command prompt
Step-by-Step
- Create a project folder – Open your terminal and run
mkdir selenium-jsthencd selenium-js. This keeps your files organized. - Initialize npm – Run
npm init -y. This creates apackage.jsonfile with default settings. - Install Selenium WebDriver – Run
npm install selenium-webdriver. This downloads the official JavaScript bindings for Selenium. - Install a browser driver – Selenium needs a driver to control your browser. For Chrome, install
chromedrivervianpm install chromedriver. For Firefox, usegeckodriver. (Alternatively, use Selenium Manager which auto-downloads drivers in newer versions.) - Create your first script – Create a file named
test.jsand open it in your editor. - Write a basic script – Add the following code:
const { Builder, By, Key, until } = require('selenium-webdriver'); (async function example() { let driver = await new Builder().forBrowser('chrome').build(); try { await driver.get('https://www.google.com'); await driver.findElement(By.name('q')).sendKeys('Selenium', Key.RETURN); await driver.wait(until.titleContains('Selenium'), 5000); console.log('Title:', await driver.getTitle()); } finally { await driver.quit(); } })(); - Run the script – In the terminal, run
node test.js. You should see a Chrome window open, search for “Selenium”, and then the page title printed in the console. - Learn to locate elements – Use
By.id,By.className,By.css, orBy.xpathto find elements. For example,driver.findElement(By.id('submit')). - Interact with forms – Use
.sendKeys()to type,.click()to click, and.clear()to clear inputs. For dropdowns, usedriver.findElement(By.css('select')).sendKeys('Option'). - Handle waits – Use
driver.wait(until.elementLocated(By.id('result')), 10000)to wait for elements to appear. Avoid fixed sleeps withdriver.sleep()as they slow tests and are unreliable. - Extract data – Use
.getText()to get text,.getAttribute('value')to get input values, and.getCssValue('color')for styles. - Take screenshots – Use
driver.takeScreenshot()and write the base64 string to a file using Node’sfsmodule. - Close the browser – Always call
await driver.quit()in afinallyblock to release resources, even if the script fails.
Common Mistakes
- Not waiting for elements – Trying to interact with an element before it’s loaded. Use explicit waits with
untilconditions. - Using wrong locators – Brittle selectors like
By.xpath('//div[1]/span')break easily. Prefer IDs, names, or CSS classes. - Forgetting to quit the driver – Leaving browsers open can exhaust memory and cause conflicts.
- Hard-coding sleeps –
driver.sleep(5000)is slow and flaky. Use waits that poll for conditions. - Not handling popups or alerts – Unexpected dialogs block execution. Use
driver.switchTo().alert()to accept or dismiss them. - Ignoring async/await – Forgetting
awaitleads to promises that never resolve, causing errors.
Tips
- Use
By.cssfor most selectors—it’s faster and more readable than XPath. - Keep your tests independent. Each test should start with a fresh browser state.
- Use page object pattern to organize selectors and actions for maintainability.
- Run tests headless (Chrome options:
--headless) for CI environments. - Set implicit waits (
driver.manage().setTimeouts({implicit: 5000})) as a fallback, but prefer explicit waits. - Use
driver.navigate().back()andforward()for multi-page flows.
Troubleshooting
“Session not created” error – Usually means the browser driver version doesn’t match your browser. Update both. For Chrome, check chrome://version and download the matching driver.
Element not found – The element might be inside an iframe. Use driver.switchTo().frame(0) to switch context. Also check if the element is hidden; you may need to scroll into view with driver.executeScript('arguments[0].scrollIntoView(true)', element).
Script hangs – Likely a wait condition never satisfied. Set a timeout and log the current URL or page source for debugging. Use driver.getPageSource().
Browser closes immediately – Ensure you’re not calling driver.quit() before the actions complete. Check your try/finally structure.
Permission errors on Linux – ChromeDriver may need executable permissions. Run chmod +x chromedriver.
Network issues – Firewalls can block driver downloads. Use a mirror or manually place the driver in your PATH.
Frequently Asked Questions
Can I use Selenium with JavaScript for web scraping?
Yes, but it’s slower than HTTP-based scrapers. Use it when the site renders content via JavaScript and you need to interact with dynamic elements.
How do I run tests in headless mode?
Add --headless to the browser options. For Chrome: new Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().addArguments('--headless')).
What is the difference between implicit and explicit waits?
Implicit waits apply a default timeout to every findElement call. Explicit waits use driver.wait with a condition, giving more control and better performance.
Can I automate multiple browsers at once?
Yes, create multiple driver instances, but be careful with resource usage. Use Promise.all to run them in parallel.
How do I handle file uploads?
Use element.sendKeys('/path/to/file') on the <input type="file"> element. Do not click the upload button.
Is Selenium still the best choice for browser automation?
It’s the most mature and widely supported. Alternatives like Playwright or Puppeteer are faster and have better APIs, but Selenium works across all major browsers.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- How to Use Multiple CSS Transforms
- How to Delete iOS Calendar Viruses
- How to Spoof Location on iPhone
- iOS App Testing on Multiple Devices: A Guide
- X Bar Symbol in Word: 3 Quick Typing Methods
- Convert Physical SIM to eSIM on iPhone: Step-by-Step