WebDriver/Selenium 2 Node.js client for browser automation and testing
—
Multi-window and frame handling for complex web applications, including window switching, sizing, and iframe navigation.
Manage browser windows, tabs, and their properties.
/**
* Open new window with URL and name
* @param url - URL to open in new window
* @param name - Window name/target
* @param cb - Callback receiving (err)
*/
newWindow(url: string, name: string, cb?: callback): void;
/**
* Close current window
* @param cb - Callback receiving (err)
*/
close(cb?: callback): void;
/**
* Switch to window by handle
* @param windowHandle - Window handle identifier
* @param cb - Callback receiving (err)
*/
window(windowHandle: string, cb?: callback): void;
/**
* Get current window handle
* @param cb - Callback receiving (err, windowHandle)
*/
windowHandle(cb?: callback): string;
/**
* Get all window handles
* @param cb - Callback receiving (err, windowHandles)
*/
windowHandles(cb?: callback): string[];
/**
* Get window name
* @param cb - Callback receiving (err, windowName)
*/
windowName(cb?: callback): string;Usage Examples:
// Get all open windows
browser.windowHandles(function(err, handles) {
console.log('Open windows:', handles.length);
handles.forEach((handle, index) => {
console.log(`Window ${index}: ${handle}`);
});
});
// Switch between windows
browser.windowHandles(function(err, handles) {
if (handles.length > 1) {
// Switch to second window
browser.window(handles[1], function(err) {
console.log('Switched to second window');
browser.title(function(err, title) {
console.log('Second window title:', title);
});
});
}
});
// Open new window and switch to it
browser.newWindow('https://example.com', 'example', function(err) {
browser.windowHandles(function(err, handles) {
// Switch to the newly opened window (usually the last one)
browser.window(handles[handles.length - 1]);
});
});
// Promise chain window management
browser
.windowHandles()
.then(handles => {
console.log('Available windows:', handles);
if (handles.length > 1) {
return browser.window(handles[1]);
}
})
.title()
.then(title => console.log('Window title:', title));Control window dimensions and screen position.
/**
* Set window size
* @param windowHandle - Window handle (or current window)
* @param width - Window width in pixels
* @param height - Window height in pixels
* @param cb - Callback receiving (err)
*/
windowSize(windowHandle: string, width: number, height: number, cb?: callback): void;
/**
* Get window size
* @param windowHandle - Window handle (or current window)
* @param cb - Callback receiving (err, size)
*/
getWindowSize(windowHandle: string, cb?: callback): {width: number, height: number};
/**
* Set current window size
* @param width - Window width in pixels
* @param height - Window height in pixels
* @param cb - Callback receiving (err)
*/
setWindowSize(width: number, height: number, cb?: callback): void;
/**
* Get window position
* @param windowHandle - Window handle
* @param cb - Callback receiving (err, position)
*/
getWindowPosition(windowHandle: string, cb?: callback): {x: number, y: number};
/**
* Set window position
* @param x - X coordinate on screen
* @param y - Y coordinate on screen
* @param cb - Callback receiving (err)
*/
setWindowPosition(x: number, y: number, cb?: callback): void;
/**
* Maximize window
* @param windowHandle - Window handle
* @param cb - Callback receiving (err)
*/
maximize(windowHandle: string, cb?: callback): void;Usage Examples:
// Set window to specific size for responsive testing
browser.setWindowSize(1024, 768, function(err) {
console.log('Window resized to tablet size');
// Take screenshot at this size
browser.saveScreenshot('tablet-view.png');
});
// Get current window dimensions
browser.getWindowSize('current', function(err, size) {
console.log('Current window size:', size.width, 'x', size.height);
});
// Position window on screen
browser.setWindowPosition(100, 100, function(err) {
console.log('Window moved to position 100,100');
});
// Maximize window for full-screen testing
browser.maximize('current', function(err) {
console.log('Window maximized');
});
// Multi-size testing
const testSizes = [
{width: 320, height: 568, name: 'mobile'},
{width: 768, height: 1024, name: 'tablet'},
{width: 1920, height: 1080, name: 'desktop'}
];
testSizes.forEach(size => {
browser.setWindowSize(size.width, size.height);
browser.saveScreenshot(`${size.name}-view.png`);
});
// Promise chain window sizing
browser
.setWindowSize(1366, 768)
.getWindowSize('current')
.then(size => {
console.log('Verified size:', size);
return browser.maximize('current');
})
.getWindowSize('current')
.then(maxSize => {
console.log('Maximized size:', maxSize);
});Navigate between frames and iframes within web pages.
/**
* Switch to frame
* @param frameRef - Frame reference (index, name, id, WebElement, or null for default)
* @param cb - Callback receiving (err)
*/
frame(frameRef: string | number | Element | null, cb?: callback): void;Usage Examples:
// Switch to frame by index
browser.frame(0, function(err) {
console.log('Switched to first frame');
// Interact with elements inside the frame
browser.elementById('frame-button', function(err, button) {
button.click();
});
});
// Switch to frame by name or id
browser.frame('payment-frame', function(err) {
console.log('Switched to payment frame');
// Fill payment form inside frame
browser.elementById('credit-card-number', function(err, input) {
input.type('4111111111111111');
});
});
// Switch to frame by element reference
browser.elementByTagName('iframe', function(err, iframe) {
browser.frame(iframe, function(err) {
console.log('Switched to iframe element');
});
});
// Switch back to default content (main page)
browser.frame(null, function(err) {
console.log('Switched back to main page');
});
// Nested frame navigation
browser
.frame('outer-frame') // Enter outer frame
.frame('inner-frame') // Enter nested frame
.elementById('nested-content') // Interact with nested content
.text()
.then(text => {
console.log('Nested frame content:', text);
return browser.frame(null); // Back to main page
});
// Complex frame interaction
browser.frame('settings-frame', function(err) {
browser.elementById('save-settings', function(err, button) {
button.click(function(err) {
// Wait for save to complete
browser.waitForElementById('success-message', 5000, function(err, message) {
message.text(function(err, text) {
console.log('Settings saved:', text);
// Switch back to main page
browser.frame(null);
});
});
});
});
});Advanced patterns for testing multi-window applications.
Usage Examples:
// Handle popup windows
browser.elementById('open-popup', function(err, button) {
button.click(function(err) {
// Wait for popup to open
browser.sleep(1000, function() {
browser.windowHandles(function(err, handles) {
if (handles.length > 1) {
// Switch to popup
browser.window(handles[1], function(err) {
// Interact with popup
browser.elementById('popup-content', function(err, content) {
content.text(function(err, text) {
console.log('Popup content:', text);
// Close popup
browser.close(function(err) {
// Switch back to main window
browser.window(handles[0]);
});
});
});
});
}
});
});
});
});
// Tab management helper
function switchToTab(tabIndex, callback) {
browser.windowHandles(function(err, handles) {
if (err) return callback(err);
if (tabIndex >= handles.length) {
return callback(new Error('Tab index out of range'));
}
browser.window(handles[tabIndex], callback);
});
}
// Usage of tab helper
switchToTab(1, function(err) {
browser.title(function(err, title) {
console.log('Second tab title:', title);
});
});
// Window cleanup utility
function closeAllWindowsExceptMain(callback) {
browser.windowHandles(function(err, handles) {
if (err) return callback(err);
const mainWindow = handles[0];
let closed = 0;
// Close all windows except the first one
for (let i = 1; i < handles.length; i++) {
browser.window(handles[i], function(err) {
if (err) return callback(err);
browser.close(function(err) {
if (err) return callback(err);
closed++;
if (closed === handles.length - 1) {
// Switch back to main window
browser.window(mainWindow, callback);
}
});
});
}
// If no windows to close, just ensure we're on main window
if (handles.length === 1) {
browser.window(mainWindow, callback);
}
});
}
// Promise-based window management
class WindowManager {
constructor(browser) {
this.browser = browser;
this.originalWindow = null;
}
async saveCurrentWindow() {
this.originalWindow = await this.browser.windowHandle();
return this.originalWindow;
}
async openNewTab(url) {
await this.browser.execute(`window.open('${url}', '_blank')`);
const handles = await this.browser.windowHandles();
return handles[handles.length - 1];
}
async switchToWindow(handle) {
await this.browser.window(handle);
return handle;
}
async closeCurrentWindow() {
await this.browser.close();
}
async returnToOriginal() {
if (this.originalWindow) {
await this.browser.window(this.originalWindow);
}
}
async closeAllExceptOriginal() {
const handles = await this.browser.windowHandles();
for (const handle of handles) {
if (handle !== this.originalWindow) {
await this.browser.window(handle);
await this.browser.close();
}
}
await this.returnToOriginal();
}
}
// Usage of WindowManager
const windowManager = new WindowManager(browser);
async function testMultipleWindows() {
await windowManager.saveCurrentWindow();
// Open multiple tabs
const tab1 = await windowManager.openNewTab('https://example.com');
const tab2 = await windowManager.openNewTab('https://google.com');
// Test each tab
await windowManager.switchToWindow(tab1);
const title1 = await browser.title();
console.log('Tab 1 title:', title1);
await windowManager.switchToWindow(tab2);
const title2 = await browser.title();
console.log('Tab 2 title:', title2);
// Clean up
await windowManager.closeAllExceptOriginal();
}Install with Tessl CLI
npx tessl i tessl/npm-wd