This example demonstrates using @nut-tree/selenium-bridge to automate a login flow by finding elements visually. The bridge redirects nut.js operations into the browser viewport controlled by Selenium WebDriver.
Basic Setup
typescript
import { Builder, Browser } from "selenium-webdriver";
import {
screen,
mouse,
keyboard,
imageResource,
centerOf,
straightTo,
Button,
} from "@nut-tree/nut-js";
import { useNlMatcher } from "@nut-tree/nl-matcher";
useNlMatcher();
import { useSelenium } from "@nut-tree/selenium-bridge";
async function main() {
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.build();
try {
// Initialize the bridge
useSelenium({ driver });
await driver.get("https://example.com/login");Visual Login Flow
typescript
// Find username field by image and type
const usernameField = await screen.find(imageResource("username-field.png"));
await mouse.move(straightTo(centerOf(usernameField)));
await mouse.click(Button.LEFT);
await keyboard.type("testuser");
// Find password field
const passwordField = await screen.find(imageResource("password-field.png"));
await mouse.move(straightTo(centerOf(passwordField)));
await mouse.click(Button.LEFT);
await keyboard.type("secretpassword");
// Find and click login button
const loginBtn = await screen.find(imageResource("login-button.png"));
await mouse.move(straightTo(centerOf(loginBtn)));
await mouse.click(Button.LEFT);
// Wait for dashboard to load (timeout: 10000ms, interval: 1000ms)
await screen.waitFor(imageResource("dashboard-header.png"), 10000, 1000);
console.log("Login successful!");
} finally {
await driver.quit();
}
}Converting Regions to WebElements
Use elementAt() to get a Selenium WebElement from a visual match. Pass the region directly:
typescript
import { Builder, Browser, WebElement } from "selenium-webdriver";
import { screen, imageResource } from "@nut-tree/nut-js";
import { useNlMatcher } from "@nut-tree/nl-matcher";
useNlMatcher();
import { useSelenium, elementAt } from "@nut-tree/selenium-bridge";
const driver = await new Builder()
.forBrowser(Browser.CHROME)
.build();
useSelenium({ driver });
await driver.get("https://example.com/products");
// Find element visually
const productCard = await screen.find(imageResource("featured-product.png"));
// Convert region to WebElement (pass the region directly)
const productElement: WebElement = await elementAt(productCard);
// Use standard Selenium methods
const productId = await productElement.getAttribute("data-product-id");
await productElement.click();Jest Integration
typescript
import { Builder, Browser, WebDriver } from "selenium-webdriver";
import { screen, mouse, imageResource, centerOf, straightTo, Button } from "@nut-tree/nut-js";
import { useNlMatcher } from "@nut-tree/nl-matcher";
useNlMatcher();
import { useSelenium } from "@nut-tree/selenium-bridge";
describe("Visual E2E Tests", () => {
let driver: WebDriver;
beforeAll(async () => {
driver = await new Builder().forBrowser(Browser.CHROME).build();
useSelenium({ driver });
});
afterAll(async () => {
await driver.quit();
});
test("should display hero section", async () => {
await driver.get("https://example.com");
const hero = await screen.find(imageResource("hero-section.png"));
expect(hero).toBeDefined();
expect(hero.width).toBeGreaterThan(500);
});
test("should open menu on click", async () => {
await driver.get("https://example.com");
const menuBtn = await screen.find(imageResource("menu-button.png"));
await mouse.move(straightTo(centerOf(menuBtn)));
await mouse.click(Button.LEFT);
const navMenu = await screen.waitFor(imageResource("nav-menu.png"), 3000, 500);
expect(navMenu).toBeDefined();
});
});Key Points
useSelenium()redirects all nut.js operations into the browser viewportelementAt(region)converts a screen region to a Selenium WebElement (pass the region directly)useNlMatcher()must be called to activate the image matching provider- Works with any Selenium-supported browser (Chrome, Firefox, Edge, Safari)
- The bridge follows the active window when switching tabs
For complete API documentation, see the Selenium Bridge docs.