Skip to content

[typescript] Add API for Creating Clean Browser State #10

Description

@bigboateng

Summary

Introduce a new API to BrowserState that enables creating a fresh browser state while preserving existing sessions until explicitly replaced. This helps manage authentication flows requiring a clean state, making session handling more seamless and reliable.

Problem

Currently, BrowserState provides mount and unmount for loading and saving browser profiles, but it lacks an efficient way to:

  • Create a clean state dynamically without affecting existing sessions immediately.
  • Seamlessly replace old sessions after successful authentication.
  • Safely discard temporary states if authentication fails.

Developers must manually check, reset, and delete sessions, making the process cumbersome and prone to errors.

Proposed Solution

Add the following new methods to BrowserState:

API Design

class BrowserState {
  /**
   * Creates a fresh browser state in a temporary directory.
   * It does not replace the existing session until explicitly committed.
   *
   * @returns A unique identifier for the clean state.
   */
  async createCleanState(): Promise<string>;

  /**
   * Commits a previously created clean state, replacing the existing session.
   *
   * @param stateId The identifier returned by `createCleanState()`.
   * @returns True if the commit was successful.
   */
  async commitCleanState(stateId: string): Promise<boolean>;

  /**
   * Discards a previously created clean state, keeping the existing session intact.
   *
   * @param stateId The identifier returned by `createCleanState()`.
   */
  async discardCleanState(stateId: string): Promise<void>;
}

Key Improvements

  1. No session ID required upfront: The API now returns a stateId when creating a clean state, making it more flexible.
  2. More structured management: The explicit stateId allows handling multiple clean states simultaneously.
  3. More robust state control: Developers explicitly commit or discard clean states, ensuring they only take effect when needed.

Usage Examples

Authentication Flow with Safe State Replacement

async function handleAuthentication(username: string, password: string) {
  const browserState = new BrowserState();

  // Create a temporary clean state
  const stateId = await browserState.createCleanState();
  const tempDir = browserState.getStatePath(stateId);

  // Launch browser with temporary clean state
  const browser = await chromium.launchPersistentContext(tempDir);
  const page = await browser.newPage();

  try {
    await page.goto('https://example.com/login');
    await page.fill('#username', username);
    await page.fill('#password', password);
    await page.click('#login-button');
    await page.waitForSelector('.login-success', { timeout: 5000 });

    // Authentication succeeded, commit the clean state
    await browserState.commitCleanState(stateId);
    return browser;
  } catch (error) {
    console.error("Authentication failed:", error);
    await browser.close();
    
    // Discard temporary state, keeping previous session intact
    await browserState.discardCleanState(stateId);
    throw new Error("Authentication failed. Please try again.");
  }
}

Benefits

Non-destructive Workflow: Clean states exist temporarily until explicitly committed.
Safer Authentication Handling: Avoids corrupting valid sessions if authentication fails.
More Flexible Usage: Developers can manage multiple clean states independently.

Implementation Considerations

  • createCleanState() generates a temporary directory and returns a unique stateId.
  • commitCleanState(stateId) replaces the current session with the clean state.
  • discardCleanState(stateId) removes the temporary state without affecting the main session.

Next Steps

  • Finalize API definitions
  • Implement functionality
  • Write tests for authentication flows
  • Update documentation and examples

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions