Skip to main content

 

Common Errors and Exceptions

  1. Timeout Errors:

    • Description: Occurs when an operation takes longer than the specified timeout.
    • Example: TimeoutError: waiting for selector "button#submit" failed: timeout 30000ms exceeded

    Handling:

    typescript
    try {
    await page.waitForSelector('button#submit', { timeout: 10000 }); } catch (error) { if (error instanceof playwright.errors.TimeoutError) { console.error("Element not found within the timeout period."); } else { throw error; // rethrow if it's not a TimeoutError } }
  2. Element Not Found:

    • Description: Trying to interact with an element that is not present in the DOM.
    • Example: Error: No node found for selector: #non-existent-element

    Handling:

    typescript
    const element = await page.$('#non-existent-element');
    if (!element) { console.error("Element not found"); } else { // Perform actions on the element }
  3. Navigation Errors:

    • Description: Errors that occur during page navigation, such as network issues or navigation to an invalid URL.
    • Example: NavigationError: net::ERR_FAILED at https://example.com

    Handling:

    typescript

    try { await page.goto('https://example.com', { waitUntil: 'load', timeout: 30000 }); } catch (error) { console.error("Failed to navigate:", error); }
  4. Assertion Errors:

    • Description: When an assertion in your test fails.
    • Example: AssertionError [ERR_ASSERTION]: 'Expected value' == 'Actual value'

    Handling:

    typescript

    try { expect(await page.title()).toBe('Expected Title'); } catch (error) { console.error("Assertion failed:", error); }
  5. Network Errors:

    • Description: Errors related to network conditions, such as failed requests or timeouts.
    • Example: NetworkError: Failed to load resource: net::ERR_CONNECTION_TIMED_OUT

    Handling:

    typescript
    page.on('requestfailed', request => {
    console.error(`Request failed: ${request.url()} ${request.failure().errorText}`); });

General Error Handling Strategies

  1. Try-Catch Blocks: Use try-catch blocks around code that can potentially throw errors to catch and handle exceptions gracefully.

    typescript

    try { await page.click('#submit-button'); } catch (error) { console.error("Error clicking submit button:", error); }
  2. Assertions with Messages: Include meaningful messages in assertions to make it easier to understand the context of a failure.

    typescript
    expect(await page.title()).toBe('Expected Title', 'Page title does not match');

  3. Custom Error Handling Functions: Create utility functions for common error handling patterns to reduce code duplication.

    typescript

    async function handleTimeoutError(fn: () => Promise<void>) { try { await fn(); } catch (error) { if (error instanceof playwright.errors.TimeoutError) { console.error("Operation timed out"); } else { throw error; } } } await handleTimeoutError(() => page.waitForSelector('button#submit'));
  4. Logging and Reporting: Use logging frameworks or services to capture and report errors. This helps in monitoring and debugging.

    typescript
    import * as fs from 'fs'; function logError(error: Error) { fs.appendFileSync('errors.log', `${new Date().toISOString()} - ${error.message}\n`); } try { await page.goto('https://example.com'); } catch (error) { logError(error); }

  5. Retry Mechanisms: Implement retry logic for operations that can fail intermittently, such as network requests.

    typescript
    async function retryOperation<T>(operation: () => Promise<T>, retries: number = 3): Promise<T> { for (let i = 0; i < retries; i++) { try { return await operation(); } catch (error) { if (i === retries - 1) throw error; } } } await retryOperation(() => page.goto('https://example.com'));

By implementing these error handling strategies, you can make your Playwright tests more robust and reliable, ensuring that your test suite can handle and recover from various types of failure

Comments

Popular posts from this blog

Get OTP from email

/** * Retrieves an OTP from Gmail in a headless tab. * @param {Object} options - The options for the function. * @param {string} options.email - The Gmail email address. * @param {string} options.password - The Gmail password. * @returns {Promise<string | null>} The OTP retrieved from the email. */ export async function getOtpFromGmail ({ email , password , } : { email : string ; password : string ; }) : Promise < string | null > { const { chromium } = require ( "playwright" ); // Launch a headless browser context for Gmail login const browser = await chromium . launch ({ headless : true }); const context = await browser . newContext (); const page = await context . newPage (); await page . goto ( "https://mail.google.com" ); const emailInput = await page . waitForSelector ( "#identifierId" ); await emailInput . fill ( email ); const emailNextButton = await page . wa...

Playwright Solution

 There is a web site need to run with browser. and which has zero downtime and alert and notifications pop up too. Third party applications are involved in and need to fix bugs too.What is the solution and how to create a framework for this scenario : need to use playwright as well 1. Understand the Requirements and Challenges: Zero Downtime: Ensure tests do not interrupt the service. Alerts and Notifications: Handle unexpected pop-ups gracefully. Third-Party Integrations: Test interactions with third-party services. Bug Fixing: Implement a process to identify and log bugs efficiently. 2. Set Up the Playwright Framework: Installation: Ensure Playwright is installed and configured. bash Copy code npm install playwright 3. Structure the Test Framework: Test Suites: Organize tests into suites (e.g., smoke tests, regression tests, integration tests). Page Object Model (POM): Use POM to manage page elements and actions. Configuration: Set up configurations for different envir...

Challenges

 One of the challenging situations I faced was identifying the correct locators for elements in our Angular application. Despite using developer tools like Chrome DevTools, it was often difficult to pinpoint the exact locators due to the complexity of the application and the dynamic nature of Angular's rendering. To overcome this, I frequently had to review the application's code in Bitbucket to understand the structure and find reliable locators. This approach allowed me to write more robust and reliable tests. Additionally, I communicated with developers to gain insights and confirm my findings, which helped streamline the process." As our application grew, the number of test scripts also increased, making the scripts larger and more chaotic. This was especially true for our end-to-end tests using Playwright and TypeScript. The test scripts became hard to manage and maintain because they contained both the test logic and the test data, leading to a lot of redundancy and ...