CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-wd

WebDriver/Selenium 2 Node.js client for browser automation and testing

Pending
Overview
Eval results
Files

window-management.mddocs/

Window & Frame Management

Multi-window and frame handling for complex web applications, including window switching, sizing, and iframe navigation.

Capabilities

Window Control

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));

Window Sizing and Positioning

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);
  });

Frame Management

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);
        });
      });
    });
  });
});

Multi-Window Testing Patterns

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

docs

browser-sessions.md

configuration.md

element-location.md

index.md

javascript-execution.md

mobile-testing.md

navigation.md

touch-actions.md

user-input.md

waiting.md

window-management.md

tile.json