Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.

Overview

๐ŸŽญ Playwright

npm version Chromium version Firefox version WebKit version

Documentation | API reference

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable and fast.

Linux macOS Windows
Chromium 99.0.4837.0 โœ… โœ… โœ…
WebKit 15.4 โœ… โœ… โœ…
Firefox 96.0.1 โœ… โœ… โœ…

Headless execution is supported for all the browsers on all platforms. Check out system requirements for details.

Usage

npm i -D playwright

This installs Playwright and browser binaries for Chromium, Firefox and WebKit. Once installed, you can require Playwright in a Node.js script and automate web browser interactions.

Capabilities

Playwright is built to automate the broad and growing set of web browser capabilities used by Single Page Apps and Progressive Web Apps.

  • Scenarios that span multiple page, domains and iframes
  • Auto-wait for elements to be ready before executing actions (like click, fill)
  • Intercept network activity for stubbing and mocking network requests
  • Emulate mobile devices, geolocation, permissions
  • Support for web components via shadow-piercing selectors
  • Native input events for mouse and keyboard
  • Upload and download files

Examples

Page screenshot

This code snippet navigates to whatsmyuseragent.org and saves a screenshot.

import { test } from '@playwright/test';

test('Page Screenshot', async ({ page }) => {
    await page.goto('http://whatsmyuseragent.org/');
    await page.screenshot({ path: `example.png` });
});

Mobile and geolocation

This snippet emulates Mobile Safari on a device at a given geolocation, navigates to maps.google.com, performs action and takes a screenshot.

import { test, devices } from '@playwright/test';

test.use({
  ...devices['iPhone 13 Pro'],
  locale: 'en-US',
  geolocation: { longitude: 12.492507, latitude: 41.889938 },
  permissions: ['geolocation'],
})

test('Mobile and geolocation', async ({ page }) => {
  await page.goto('https://maps.google.com');
  await page.locator('text="Your location"').click();
  await page.waitForRequest(/.*preview\/pwa/);
  await page.screenshot({ path: 'colosseum-iphone.png' });
});

Evaluate in browser context

This code snippet navigates to example.com, and executes a script in the page context.

import { test } from '@playwright/test';

test('Evaluate in browser context', async ({ page }) => {
  await page.goto('https://www.example.com/');
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    }
  });
  console.log(dimensions);
});

Intercept network requests

This code snippet sets up request routing for a page to log all network requests.

import { test } from '@playwright/test';

test('Intercept network requests', async ({ page }) => {
  // Log and continue all network requests
  await page.route('**', route => {
    console.log(route.request().url());
    route.continue();
  });
  await page.goto('http://todomvc.com');
});

Resources

Comments
  • [BUG] Failed to launch chromium because executable doesn't exist

    [BUG] Failed to launch chromium because executable doesn't exist

    Edit from the Playwright team ๐Ÿ“ฃ

    npx playwright install
    

    Will fix it and install your browsers as expected.


    I am attempting to install Playwright but cannot get past the following error when trying to run a basic test:

       Failed to launch chromium because executable doesn't exist at /Users/danawoodman/Library/Caches/ms-playwright/chromium-799411/chrome-mac/Chromium.app/Contents/MacOS/Chromium
        Try re-installing playwright with "npm install playwright"
        Note: use DEBUG=pw:api environment variable and rerun to capture Playwright logs.
    
          at Chromium._launchProcess (node_modules/playwright/lib/server/browserType.js:123:19)
          at async Chromium._innerLaunch (node_modules/playwright/lib/server/browserType.js:66:75)
          at async ProgressController.run (node_modules/playwright/lib/server/progress.js:74:28)
          at async Chromium.launch (node_modules/playwright/lib/server/browserType.js:54:25)
          at async BrowserServerLauncherImpl.launchServer (node_modules/playwright/lib/browserServerImpl.js:32:25)
          at async PlaywrightRunner.getTests (node_modules/jest-playwright-preset/lib/PlaywrightRunner.js:56:56)
          at async PlaywrightRunner.runTests (node_modules/jest-playwright-preset/lib/PlaywrightRunner.js:87:30)
          at async TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:321:13)
          at async runJest (node_modules/@jest/core/build/runJest.js:372:19)
    

    The file ~/Library/Caches/ms-playwright/chromium-799411/chrome-mac/Chromium.app/Contents/MacOS/Chromium does not exist but this folder does ~/Library/Caches/ms-playwright/chromium-799411/chrome-mac/Chromium.app/Contents/Frameworks/Chromium\ Framework.framework. Not sure why it is looking in the wrong location?

    I have ran yarn add playwright and the package appears to install successfully. I've also tried to manually run node node_modules/playwright/install.js which gives me:

    Removing unused browser at /Users/danawoodman/Library/Caches/ms-playwright/chromium-799411
    Downloading chromium v799411 - 118.1 Mb [====================] 100% 0.0s
    

    I've also attempted to remove node_modules, yarn.lock and ~/Library/Caches/ms-playwright to reset things to a clean state but nothing is working. I'm at a losss for what to do and Googling/searching issues doesn't get me anything useful.

    I don't think there is anything particularly unique with my setup.

    Is there a way to better troubleshoot why I can't get Playwright to work?

    opened by danawoodman 45
  • [Question] Attaching playwright to an existing browser window?

    [Question] Attaching playwright to an existing browser window?

    Hey,

    First of all thank you for this wonderful library <3

    I'm working on a feature for playwright recorder to let you more easily run playwright tests from the browser.

    I want to attach playwright to a context that is already running (opened with ChromeDriver if that matters):

        const browser = await playwright.chromium.connect({
            wsEndpoint: cdpUrl,
        });
        const contexts = browser.contexts(); // empty
    
        // how do I get the existing already open pages?
    
        const context = await browser.newContext({viewport: null })
        const pages = await context.pages(); // empty
    

    I checked puppeteer and it was easy to get working like this:

        const browser = await puppeteer.connect({
            browserWSEndpoint: cdpUrl,
            defaultViewport: null, // disable puppeteer resize
            product: 'chrome', 
        });
        const pages = await browser.pages();
    
        const page = last(pages);
    

    Is there an official method to obtain existing browser contexts?

    opened by benjamingr 44
  • No Test Found

    No Test Found

    • Using Windows 10 & VS Code v1.64.2 (user setup)
    • Install Microsoft's official Playwright extension v0.2.1
    • Add Playwright to project with Ctrl-Shift-P and typing install playwright
    • Click on the Testing Icon on the Activity bar to open Playwright extension pane
    • No tests are found
    • No green play buttons to run isolated tests in the test file image
    P3-collecting-feedback 
    opened by gtodd876 41
  • [BUG] File uploads fail which are > 50 MB

    [BUG] File uploads fail which are > 50 MB

    Context:

    • Playwright Version: 1.3.0
    • Operating System: Windows
    • Node.js version: 12.18.3
    • Browser: Chromium

    Code Snippet

    const { chromium } = require("playwright");
    
    (async () => {
      const browser = await chromium.launch();
      const page = await browser.newPage();
      await page.setContent(
        '<input type="file" name="fileToUpload" id="fileToUpload">'
      );
      await page.setInputFiles("input", "path/to/large/file.txt");
      await browser.close();
    })();
    
    

    Describe the bug When uploading large file, about 100MB, page.setInputFiles fails. With Firefox and Webkit it takes some time but it works. Log:

      pw:api => page.setContent started +0ms
      pw:api setting frame content, waiting until "load" [] +1ms
      pw:api <= page.setContent succeeded +79ms
      pw:api => page.setInputFiles started +2ms
      pw:api waiting for selector "input" [] +1ms
      pw:api   selector resolved to visible <input type="file" id="fileToUpload" name="fileToUpload"/> [] +26ms
      pw:api <= page.setInputFiles failed +1s
    (node:19668) UnhandledPromiseRejectionWarning: page.setInputFiles: Protocol error (Runtime.callFunctionOn): Target closed.
    =========================== logs ===========================
    [api] waiting for selector "input"
    [api]   selector resolved to visible <input type="file" id="fileToUpload" name="fileToUpload"/>
    ============================================================
    Note: use DEBUG=pw:api environment variable and rerun to capture Playwright logs.Error
        at C:\dev\playwright\node_modules\playwright\lib\chromium\crConnection.js:131:63
        at new Promise (<anonymous>)
        at CRSession.send (C:\dev\playwright\node_modules\playwright\lib\chromium\crConnection.js:130:16)
        at CRSession.send (C:\dev\playwright\node_modules\playwright\lib\helper.js:80:31)
        at CRExecutionContext.evaluateWithArguments (C:\dev\playwright\node_modules\playwright\lib\chromium\crExecutionContext.js:40:79)
        at evaluateExpression (C:\dev\playwright\node_modules\playwright\lib\javascript.js:164:40)
        at async FrameManager.waitForSignalsCreatedBy (C:\dev\playwright\node_modules\playwright\lib\frames.js:90:24)
        at async FrameExecutionContext.evaluateInternal (C:\dev\playwright\node_modules\playwright\lib\dom.js:36:16)
        at async CRPage.setInputFiles (C:\dev\playwright\node_modules\playwright\lib\chromium\crPage.js:210:9)
        at async C:\dev\playwright\node_modules\playwright\lib\dom.js:440:13
      -- ASYNC --
        at CRSession.send (C:\dev\playwright\node_modules\playwright\lib\helper.js:79:23)
        at CRExecutionContext.evaluateWithArguments (C:\dev\playwright\node_modules\playwright\lib\chromium\crExecutionContext.js:40:79)
        at evaluateExpression (C:\dev\playwright\node_modules\playwright\lib\javascript.js:164:40)
        at async FrameManager.waitForSignalsCreatedBy (C:\dev\playwright\node_modules\playwright\lib\frames.js:90:24)
        at async FrameExecutionContext.evaluateInternal (C:\dev\playwright\node_modules\playwright\lib\dom.js:36:16)
        at async CRPage.setInputFiles (C:\dev\playwright\node_modules\playwright\lib\chromium\crPage.js:210:9)
        at async C:\dev\playwright\node_modules\playwright\lib\dom.js:440:13
        at async FrameManager.waitForSignalsCreatedBy (C:\dev\playwright\node_modules\playwright\lib\frames.js:90:24)
        at async ElementHandle._setInputFiles (C:\dev\playwright\node_modules\playwright\lib\dom.js:438:9)
        at async C:\dev\playwright\node_modules\playwright\lib\frames.js:674:32
      -- ASYNC --
        at Frame.setInputFiles (C:\dev\playwright\node_modules\playwright\lib\helper.js:79:23)
        at C:\dev\playwright\node_modules\playwright\lib\page.js:407:61
        at Page._attributeToPage (C:\dev\playwright\node_modules\playwright\lib\page.js:370:20)
        at Page.setInputFiles (C:\dev\playwright\node_modules\playwright\lib\page.js:407:21)
        at Page.setInputFiles (C:\dev\playwright\node_modules\playwright\lib\helper.js:80:31)
        at C:\dev\playwright\upload.js:9:14
    (node:19668) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
    (node:19668) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    
    opened by adambbn 39
  • [BUG] browserType.launch: Protocol error (Browser.enable): Browser closed

    [BUG] browserType.launch: Protocol error (Browser.enable): Browser closed

    Context:

    • Playwright Version: 1.17.1
    • Operating System: Mac
    • Node.js version: 14.x
    • Browser: All
    • Extra: Azure pipelines CI run

    Code Snippet

    playwright.chromium.launch();
    

    Describe the bug

    We had a failing Azure pipelines CI run in https://dev.azure.com/monacotools/Monaco/_build/results?buildId=148061&view=logs&j=3792f238-f35e-5f82-0dbc-272432d9a0fb&t=0d7e5bc9-922f-51dd-b06a-a90d0b9feeeb&l=13 with the following output printed:

    Starting: Run unit tests (Browser, Chromium & Firefox & Webkit)
    ==============================================================================
    Task         : Command line
    Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
    Version      : 2.182.0
    Author       : Microsoft Corporation
    Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
    ==============================================================================
    Generating script.
    ========================== Starting Command Output ===========================
    /bin/bash --noprofile --norc /Users/runner/work/_temp/0b41947a-56e7-4f3d-ba2f-309cb70379dc.sh
    yarn run v1.22.17
    $ node test/unit/browser/index.js --build --browser chromium --browser webkit --browser firefox --tfs 'Browser Unit Tests'
    browserType.launch: Protocol error (Browser.enable): Browser closed.
    ==================== Browser output: ====================
    <launching> /Users/runner/Library/Caches/ms-playwright/firefox-1304/firefox/Nightly.app/Contents/MacOS/firefox -no-remote -headless -profile /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/playwright_firefoxdev_profile-8oqYFV -juggler-pipe -silent
    <launched> pid=11682
    [pid=11682][err] *** You are running in headless mode.
    =========================== logs ===========================
    <launching> /Users/runner/Library/Caches/ms-playwright/firefox-1304/firefox/Nightly.app/Contents/MacOS/firefox -no-remote -headless -profile /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/playwright_firefoxdev_profile-8oqYFV -juggler-pipe -silent
    <launched> pid=11682
    [pid=11682][err] *** You are running in headless mode.
    ============================================================
        at runTestsInBrowser (/Users/runner/work/1/s/test/unit/browser/index.js:127:48)
        at /Users/runner/work/1/s/test/unit/browser/index.js:239:17
        at /Users/runner/work/1/s/test/unit/browser/index.js:237:32 {
      name: 'Error'
    }
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
    ##[error]Bash exited with code '1'.
    Finishing: Run unit tests (Browser, Chromium & Firefox & Webkit)
    

    Asking here for advice if there is something we can do about it.

    browser-firefox 
    opened by bpasero 37
  • [BUG] Timeout of 30000ms exceeded while running fixture

    [BUG] Timeout of 30000ms exceeded while running fixture "browser" setup. (using Firefox)

    Context:

    • Playwright Version: 1.22
    • Operating System: Ubuntu
    • Node.js version: v16.15.0
    • Browser: Firefox
    • Extra: Run using TeamCity, on a Linux VM with a Docker TeamCity build agent and the Playwright Docker container

    Code Snippet

    Help us help you! Put down a short code snippet that illustrates your bug and that we can run and debug locally. For example:

    import { test, expect, Page } from '@playwright/test';
    
    test.beforeEach(async ({ page }) => {
      await page.goto('https://demo.playwright.dev/todomvc');
    });
    
    const TODO_ITEMS = [
      'buy some cheese',
      'feed the cat',
      'book a doctors appointment'
    ];
    
    test.describe('New Todo', () => {
      test('should allow me to add todo items', async ({ page }) => {
        // Create 1st todo.
        await page.locator('.new-todo').fill(TODO_ITEMS[0]);
        await page.locator('.new-todo').press('Enter');
    
        // Make sure the list only has one todo item.
        await expect(page.locator('.view label')).toHaveText([
          TODO_ITEMS[0]
        ]);
    
        // Create 2nd todo.
        await page.locator('.new-todo').fill(TODO_ITEMS[1]);
        await page.locator('.new-todo').press('Enter');
    
        // Make sure the list now has two todo items.
        await expect(page.locator('.view label')).toHaveText([
          TODO_ITEMS[0],
          TODO_ITEMS[1]
        ]);
    
        await checkNumberOfTodosInLocalStorage(page, 2);
      });
    
      test('should clear text input field when an item is added', async ({ page }) => {
        // Create one todo item.
        await page.locator('.new-todo').fill(TODO_ITEMS[0]);
        await page.locator('.new-todo').press('Enter');
    
        // Check that input is empty.
        await expect(page.locator('.new-todo')).toBeEmpty();
        await checkNumberOfTodosInLocalStorage(page, 1);
      });
    
      test('should append new items to the bottom of the list', async ({ page }) => {
        // Create 3 items.
        await createDefaultTodos(page);
    
        // Check test using different methods.
        await expect(page.locator('.todo-count')).toHaveText('3 items left');
        await expect(page.locator('.todo-count')).toContainText('3');
        await expect(page.locator('.todo-count')).toHaveText(/3/);
    
        // Check all items in one call.
        await expect(page.locator('.view label')).toHaveText(TODO_ITEMS);
        await checkNumberOfTodosInLocalStorage(page, 3);
      });
    
      test('should show #main and #footer when items added', async ({ page }) => {
        await page.locator('.new-todo').fill(TODO_ITEMS[0]);
        await page.locator('.new-todo').press('Enter');
    
        await expect(page.locator('.main')).toBeVisible();
        await expect(page.locator('.footer')).toBeVisible();
        await checkNumberOfTodosInLocalStorage(page, 1);
      });
    });
    
    test.describe('Mark all as completed', () => {
      test.beforeEach(async ({ page }) => {
        await createDefaultTodos(page);
        await checkNumberOfTodosInLocalStorage(page, 3);
      });
    
      test.afterEach(async ({ page }) => {
        await checkNumberOfTodosInLocalStorage(page, 3);
      });
    
      test('should allow me to mark all items as completed', async ({ page }) => {
        // Complete all todos.
        await page.locator('.toggle-all').check();
    
        // Ensure all todos have 'completed' class.
        await expect(page.locator('.todo-list li')).toHaveClass(['completed', 'completed', 'completed']);
        await checkNumberOfCompletedTodosInLocalStorage(page, 3);
      });
    
      test('should allow me to clear the complete state of all items', async ({ page }) => {
        // Check and then immediately uncheck.
        await page.locator('.toggle-all').check();
        await page.locator('.toggle-all').uncheck();
    
        // Should be no completed classes.
        await expect(page.locator('.todo-list li')).toHaveClass(['', '', '']);
      });
    
      test('complete all checkbox should update state when items are completed / cleared', async ({ page }) => {
        const toggleAll = page.locator('.toggle-all');
        await toggleAll.check();
        await expect(toggleAll).toBeChecked();
        await checkNumberOfCompletedTodosInLocalStorage(page, 3);
    
        // Uncheck first todo.
        const firstTodo = page.locator('.todo-list li').nth(0);
        await firstTodo.locator('.toggle').uncheck();
    
        // Reuse toggleAll locator and make sure its not checked.
        await expect(toggleAll).not.toBeChecked();
    
        await firstTodo.locator('.toggle').check();
        await checkNumberOfCompletedTodosInLocalStorage(page, 3);
    
        // Assert the toggle all is checked again.
        await expect(toggleAll).toBeChecked();
      });
    });
    
    test.describe('Item', () => {
    
      test('should allow me to mark items as complete', async ({ page }) => {
        // Create two items.
        for (const item of TODO_ITEMS.slice(0, 2)) {
          await page.locator('.new-todo').fill(item);
          await page.locator('.new-todo').press('Enter');
        }
    
        // Check first item.
        const firstTodo = page.locator('.todo-list li').nth(0);
        await firstTodo.locator('.toggle').check();
        await expect(firstTodo).toHaveClass('completed');
    
        // Check second item.
        const secondTodo = page.locator('.todo-list li').nth(1);
        await expect(secondTodo).not.toHaveClass('completed');
        await secondTodo.locator('.toggle').check();
    
        // Assert completed class.
        await expect(firstTodo).toHaveClass('completed');
        await expect(secondTodo).toHaveClass('completed');
      });
    
      test('should allow me to un-mark items as complete', async ({ page }) => {
        // Create two items.
        for (const item of TODO_ITEMS.slice(0, 2)) {
          await page.locator('.new-todo').fill(item);
          await page.locator('.new-todo').press('Enter');
        }
    
        const firstTodo = page.locator('.todo-list li').nth(0);
        const secondTodo = page.locator('.todo-list li').nth(1);
        await firstTodo.locator('.toggle').check();
        await expect(firstTodo).toHaveClass('completed');
        await expect(secondTodo).not.toHaveClass('completed');
        await checkNumberOfCompletedTodosInLocalStorage(page, 1);
    
        await firstTodo.locator('.toggle').uncheck();
        await expect(firstTodo).not.toHaveClass('completed');
        await expect(secondTodo).not.toHaveClass('completed');
        await checkNumberOfCompletedTodosInLocalStorage(page, 0);
      });
    
      test('should allow me to edit an item', async ({ page }) => {
        await createDefaultTodos(page);
    
        const todoItems = page.locator('.todo-list li');
        const secondTodo = todoItems.nth(1);
        await secondTodo.dblclick();
        await expect(secondTodo.locator('.edit')).toHaveValue(TODO_ITEMS[1]);
        await secondTodo.locator('.edit').fill('buy some sausages');
        await secondTodo.locator('.edit').press('Enter');
    
        // Explicitly assert the new text value.
        await expect(todoItems).toHaveText([
          TODO_ITEMS[0],
          'buy some sausages',
          TODO_ITEMS[2]
        ]);
        await checkTodosInLocalStorage(page, 'buy some sausages');
      });
    });
    
    test.describe('Editing', () => {
      test.beforeEach(async ({ page }) => {
        await createDefaultTodos(page);
        await checkNumberOfTodosInLocalStorage(page, 3);
      });
    
      test('should hide other controls when editing', async ({ page }) => {
        const todoItem = page.locator('.todo-list li').nth(1);
        await todoItem.dblclick();
        await expect(todoItem.locator('.toggle')).not.toBeVisible();
        await expect(todoItem.locator('label')).not.toBeVisible();
        await checkNumberOfTodosInLocalStorage(page, 3);
      });
    
      test('should save edits on blur', async ({ page }) => {
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(1).dblclick();
        await todoItems.nth(1).locator('.edit').fill('buy some sausages');
        await todoItems.nth(1).locator('.edit').dispatchEvent('blur');
    
        await expect(todoItems).toHaveText([
          TODO_ITEMS[0],
          'buy some sausages',
          TODO_ITEMS[2],
        ]);
        await checkTodosInLocalStorage(page, 'buy some sausages');
      });
    
      test('should trim entered text', async ({ page }) => {
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(1).dblclick();
        await todoItems.nth(1).locator('.edit').fill('    buy some sausages    ');
        await todoItems.nth(1).locator('.edit').press('Enter');
    
        await expect(todoItems).toHaveText([
          TODO_ITEMS[0],
          'buy some sausages',
          TODO_ITEMS[2],
        ]);
        await checkTodosInLocalStorage(page, 'buy some sausages');
      });
    
      test('should remove the item if an empty text string was entered', async ({ page }) => {
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(1).dblclick();
        await todoItems.nth(1).locator('.edit').fill('');
        await todoItems.nth(1).locator('.edit').press('Enter');
    
        await expect(todoItems).toHaveText([
          TODO_ITEMS[0],
          TODO_ITEMS[2],
        ]);
      });
    
      test('should cancel edits on escape', async ({ page }) => {
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(1).dblclick();
        await todoItems.nth(1).locator('.edit').press('Escape');
        await expect(todoItems).toHaveText(TODO_ITEMS);
      });
    });
    
    test.describe('Counter', () => {
      test('should display the current number of todo items', async ({ page }) => {
        await page.locator('.new-todo').fill(TODO_ITEMS[0]);
        await page.locator('.new-todo').press('Enter');
        await expect(page.locator('.todo-count')).toContainText('1');
    
        await page.locator('.new-todo').fill(TODO_ITEMS[1]);
        await page.locator('.new-todo').press('Enter');
        await expect(page.locator('.todo-count')).toContainText('2');
    
        await checkNumberOfTodosInLocalStorage(page, 2);
      });
    });
    
    test.describe('Clear completed button', () => {
      test.beforeEach(async ({ page }) => {
        await createDefaultTodos(page);
      });
    
      test('should display the correct text', async ({ page }) => {
        await page.locator('.todo-list li .toggle').first().check();
        await expect(page.locator('.clear-completed')).toHaveText('Clear completed');
      });
    
      test('should remove completed items when clicked', async ({ page }) => {
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(1).locator('.toggle').check();
        await page.locator('.clear-completed').click();
        await expect(todoItems).toHaveCount(2);
        await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
      });
    
      test('should be hidden when there are no items that are completed', async ({ page }) => {
        await page.locator('.todo-list li .toggle').first().check();
        await page.locator('.clear-completed').click();
        await expect(page.locator('.clear-completed')).toBeHidden();
      });
    });
    
    test.describe('Persistence', () => {
      test('should persist its data', async ({ page }) => {
        for (const item of TODO_ITEMS.slice(0, 2)) {
          await page.locator('.new-todo').fill(item);
          await page.locator('.new-todo').press('Enter');
        }
    
        const todoItems = page.locator('.todo-list li');
        await todoItems.nth(0).locator('.toggle').check();
        await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
        await expect(todoItems).toHaveClass(['completed', '']);
    
        // Ensure there is 1 completed item.
        checkNumberOfCompletedTodosInLocalStorage(page, 1);
    
        // Now reload.
        await page.reload();
        await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
        await expect(todoItems).toHaveClass(['completed', '']);
      });
    });
    
    test.describe('Routing', () => {
      test.beforeEach(async ({ page }) => {
        await createDefaultTodos(page);
        // make sure the app had a chance to save updated todos in storage
        // before navigating to a new view, otherwise the items can get lost :(
        // in some frameworks like Durandal
        await checkTodosInLocalStorage(page, TODO_ITEMS[0]);
      });
    
      test('should allow me to display active items', async ({ page }) => {
        await page.locator('.todo-list li .toggle').nth(1).check();
        await checkNumberOfCompletedTodosInLocalStorage(page, 1);
        await page.locator('.filters >> text=Active').click();
        await expect(page.locator('.todo-list li')).toHaveCount(2);
        await expect(page.locator('.todo-list li')).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
      });
    
      test('should respect the back button', async ({ page }) => {
        await page.locator('.todo-list li .toggle').nth(1).check();
        await checkNumberOfCompletedTodosInLocalStorage(page, 1);
    
        await test.step('Showing all items', async () => {
          await page.locator('.filters >> text=All').click();
          await expect(page.locator('.todo-list li')).toHaveCount(3);
        });
    
        await test.step('Showing active items', async () => {
          await page.locator('.filters >> text=Active').click();
        });
    
        await test.step('Showing completed items', async () => {
          await page.locator('.filters >> text=Completed').click();
        });
    
        await expect(page.locator('.todo-list li')).toHaveCount(1);
        await page.goBack();
        await expect(page.locator('.todo-list li')).toHaveCount(2);
        await page.goBack();
        await expect(page.locator('.todo-list li')).toHaveCount(3);
      });
    
      test('should allow me to display completed items', async ({ page }) => {
        await page.locator('.todo-list li .toggle').nth(1).check();
        await checkNumberOfCompletedTodosInLocalStorage(page, 1);
        await page.locator('.filters >> text=Completed').click();
        await expect(page.locator('.todo-list li')).toHaveCount(1);
      });
    
      test('should allow me to display all items', async ({ page }) => {
        await page.locator('.todo-list li .toggle').nth(1).check();
        await checkNumberOfCompletedTodosInLocalStorage(page, 1);
        await page.locator('.filters >> text=Active').click();
        await page.locator('.filters >> text=Completed').click();
        await page.locator('.filters >> text=All').click();
        await expect(page.locator('.todo-list li')).toHaveCount(3);
      });
    
      test('should highlight the currently applied filter', async ({ page }) => {
        await expect(page.locator('.filters >> text=All')).toHaveClass('selected');
        await page.locator('.filters >> text=Active').click();
        // Page change - active items.
        await expect(page.locator('.filters >> text=Active')).toHaveClass('selected');
        await page.locator('.filters >> text=Completed').click();
        // Page change - completed items.
        await expect(page.locator('.filters >> text=Completed')).toHaveClass('selected');
      });
    });
    
    async function createDefaultTodos(page: Page) {
      for (const item of TODO_ITEMS) {
        await page.locator('.new-todo').fill(item);
        await page.locator('.new-todo').press('Enter');
      }
    }
    
    async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
      return await page.waitForFunction(e => {
        return JSON.parse(localStorage['react-todos']).length === e;
      }, expected);
    }
    
    async function checkNumberOfCompletedTodosInLocalStorage(page: Page, expected: number) {
      return await page.waitForFunction(e => {
        return JSON.parse(localStorage['react-todos']).filter((todo: any) => todo.completed).length === e;
      }, expected);
    }
    
    async function checkTodosInLocalStorage(page: Page, title: string) {
      return await page.waitForFunction(t => {
        return JSON.parse(localStorage['react-todos']).map((todo: any) => todo.title).includes(t);
      }, title);
    }
    

    Describe the bug

    I have other code I am using for this, but I was able to reproduce the issue with the default example tests provided here that Playwright provides when downloading it. I am running my tests on TeamCity. I have a Linux VM with a TeamCity build agent Docker container. I am also using the Docker container from Playwright to run the tests in. So far, the tests run fine in Chromium and Safari. However, I get the following error when trying to run them in Firefox: Timeout of 30000ms exceeded while running fixture "browser" setup. at /opt/buildagent/work/6f7a18f2c8f56a5c/PolicyTechAutomationTests/tests/smoketestshould.spec.ts:94:6 That line in my code (which is different than the code pasted here) is: test.beforeAll(async ({ browser }) => { I am able to run these tests using Firefox on my local environment without issue. It is almost as if the Playwright Docker container is acting like Firefox does not exist.

    P3-collecting-feedback browser-firefox 
    opened by eatonjl 36
  • [BUG] WebKit linux-arm64 crash when navigating to specific site

    [BUG] WebKit linux-arm64 crash when navigating to specific site

    Context:

    • Playwright Version: 1.24.2
    • Operating System: Mac OS
    • Node.js version: 16.16.0
    • Browser: Webkit
    • Extra: Using Docker Playwright image

    Describe the bug

    When I run a certain set of dests with Webkit locally on my machine, they pass just fine. If, however, I run them in the Playwright Docker image, the tests will randomly fail with the error "Target Closed". I ran it with the debugger line, and this was the output. I would love if someone could take a look and see why running in the Docker image causes it to behave differently, or more information about what "target" closed" could mean.

    Running 3 tests using 1 worker
    
      pw:browser <launching> /ms-playwright/chromium-1015/chrome-linux/chrome --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-1pAMGJ --remote-debugging-pipe --no-startup-window +0ms
      pw:browser <launched> pid=2950 +5ms
      pw:browser [pid=2950][err] [0804/154052.885702:ERROR:bus.cc(398)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory +47ms
      pw:browser [pid=2950][err] [0804/154052.885846:ERROR:bus.cc(398)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory +0ms
      pw:browser [pid=2950][err] [0804/154052.896239:WARNING:bluez_dbus_manager.cc(247)] Floss manager not present, cannot set Floss enable/disable. +10ms
      pw:browser [pid=2950][err] [0804/154052.903427:WARNING:sandbox_linux.cc(376)] InitializeSandbox() called with multiple threads in process gpu-process. +7ms
      pw:browser [pid=2950][err] [0804/154055.339251:ERROR:cert_issuer_source_aia.cc(134)] AiaRequest::OnFetchCompleted got error -301 +2s
      pw:browser [pid=2950][err] [0804/154055.340353:ERROR:cert_issuer_source_aia.cc(134)] AiaRequest::OnFetchCompleted got error -301 +1ms
      pw:browser [pid=2950][err] [0804/154055.340471:ERROR:cert_verify_proc_builtin.cc(690)] CertVerifyProcBuiltin for doorman.qa1.gw.navex-pe.com failed: +1ms
      pw:browser [pid=2950][err] ----- Certificate i=1 (CN=OBIWANDC,0.9.2342.19200300.100.1.25=#796F6461,0.9.2342.19200300.100.1.25=#6C6F63616C) ----- +1ms
      pw:browser [pid=2950][err] ERROR: No matching issuer found +6ms
      pw:browser [pid=2950][err]  +0ms
      pw:browser [pid=2950][err]  +0ms
      pw:browser [pid=2950][err] [0804/154055.343804:ERROR:ssl_client_socket_impl.cc(983)] handshake failed; returned -1, SSL error code 1, net_error -202 +0ms
      pw:browser [pid=2950][err] [0804/154055.425434:ERROR:ssl_client_socket_impl.cc(983)] handshake failed; returned -1, SSL error code 1, net_error -202 +75ms
      pw:browser [pid=2950][err] [0804/154056.429421:ERROR:cert_issuer_source_aia.cc(134)] AiaRequest::OnFetchCompleted got error -301 +1s
      pw:browser [pid=2950][err] [0804/154056.430818:ERROR:cert_issuer_source_aia.cc(134)] AiaRequest::OnFetchCompleted got error -301 +2ms
      pw:browser [pid=2950][err] [0804/154056.430917:ERROR:cert_verify_proc_builtin.cc(690)] CertVerifyProcBuiltin for id1.qa1.gw.navex-pe.com failed: +0ms
      pw:browser [pid=2950][err] ----- Certificate i=1 (CN=OBIWANDC,0.9.2342.19200300.100.1.25=#796F6461,0.9.2342.19200300.100.1.25=#6C6F63616C) ----- +0ms
      pw:browser [pid=2950][err] ERROR: No matching issuer found +7ms
      pw:browser [pid=2950][err]  +0ms
      pw:browser [pid=2950][err]  +0ms
      pw:browser [pid=2950][err] [0804/154056.432131:ERROR:ssl_client_socket_impl.cc(983)] handshake failed; returned -1, SSL error code 1, net_error -202 +4ms
      pw:browser [pid=2950][err] [0804/154056.535670:ERROR:ssl_client_socket_impl.cc(983)] handshake failed; returned -1, SSL error code 1, net_error -202 +99ms
      pw:browser [pid=2950] <gracefully close start> +8s
      pw:browser [pid=2950] <process did exit: exitCode=0, signal=null> +23ms
      pw:browser [pid=2950] starting temporary directories cleanup +0ms
      pw:browser [pid=2950] finished temporary directories cleanup +9ms
      pw:browser [pid=2950] <gracefully close end> +0ms
      โœ˜  [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:37:2 โ€บ Draft Document โ€บ Save New Document (17s)
      pw:browser <launching> /ms-playwright/webkit-1683/pw_run.sh --inspector-pipe --headless --no-startup-window +0ms
      pw:browser <launched> pid=3462 +3ms
      pw:browser [pid=3462] <gracefully close start> +17s
      pw:browser [pid=3462] <process did exit: exitCode=0, signal=null> +11ms
      pw:browser [pid=3462] starting temporary directories cleanup +0ms
      pw:browser [pid=3462] finished temporary directories cleanup +25ms
      pw:browser [pid=3462] <gracefully close end> +0ms
      โœ˜  [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:54:2 โ€บ Collaboration Document โ€บ Send Draft Document To Writers (15s)
      pw:browser <launching> /ms-playwright/webkit-1683/pw_run.sh --inspector-pipe --headless --no-startup-window +0ms
      pw:browser <launched> pid=4024 +2ms
      pw:browser [pid=4024] <gracefully close start> +16s
      pw:browser [pid=4024] <process did exit: exitCode=0, signal=null> +11ms
      pw:browser [pid=4024] starting temporary directories cleanup +0ms
      pw:browser [pid=4024] finished temporary directories cleanup +24ms
      pw:browser [pid=4024] <gracefully close end> +0ms
      โœ˜  [webkit] โ€บ e2etests/reviewandapprovalshould.spec.ts:41:2 โ€บ Review Document2 โ€บ Send Document To Review (35s)
      pw:browser <launching> /ms-playwright/webkit-1683/pw_run.sh --inspector-pipe --headless --no-startup-window +0ms
      pw:browser <launched> pid=4584 +3ms
      pw:browser [pid=4584] <gracefully close start> +35s
      pw:browser [pid=4584] <process did exit: exitCode=0, signal=null> +13ms
      pw:browser [pid=4584] starting temporary directories cleanup +0ms
      pw:browser [pid=4584] finished temporary directories cleanup +39ms
      pw:browser [pid=4584] <gracefully close end> +1ms
    
    
      1) [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:37:2 โ€บ Draft Document โ€บ Save New Document 
    
        locator.click: Target closed
        =========================== logs ===========================
          waiting for frame "iframe[name="Frame_PPMPopupIFrame"]"
          selector resolved to visible <iframe tabindex="0" role="document" id="Frame_PPMPopupIโ€ฆ></iframe>
        waiting for selector "iframe[name="Frame_PPMPopupIFrame"] >> control=enter-frame >> id=DeleteToolbarButton"
        ============================================================
    
          19 | 	await policyTechDocumentPage.clickContentTopMenuMoreButton();
          20 | 	await policyTechDocumentPage.clickContentTopMenuArchiveButton();
        > 21 | 	await policyTechDocumentPage.clickContentArchiveConfirmationPopupYesButton();
             | 	                             ^
          22 | 	const policyTechSidebar = new PolicyTechSidebar(page);
          23 | 	await policyTechSidebar.clickSettingsAndToolsTab();
          24 | 	await policyTechSidebar.clickToolsSubTab();
    
            at PolicyTechDocumentPage.clickContentArchiveConfirmationPopupYesButton (/tests/tests/PageObjectModels/PolicyTech/ContentWindows/content.ts:111:55)
            at /tests/tests/e2etests/draftandcollaborationshould.spec.ts:21:31
    
        attachment #1: trace (application/zip) ---------------------------------------------------------
        test-results/e2etests-draftandcollaborationshould-Draft-Document-Save-New-Document-webkit/trace.zip
        Usage:
    
            npx playwright show-trace test-results/e2etests-draftandcollaborationshould-Draft-Document-Save-New-Document-webkit/trace.zip
    
        ------------------------------------------------------------------------------------------------
    
      2) [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:54:2 โ€บ Collaboration Document โ€บ Send Draft Document To Writers 
    
        locator.check: Target closed
        =========================== logs ===========================
          waiting for frame "iframe[name="WizardPanelPropertiesEdit_Iframe"]"
          selector resolved to visible <iframe width="100%" height="100%" marginwidth="0" frameโ€ฆ></iframe>
          waiting for frame "#UserFinderFrame"
        ============================================================
    
          66 | 		await policyTechDocumentPage.clickContentPropertyWizardSaveButton();
          67 | 		await policyTechDocumentPage.clickPropertiesWizardWritersStepTab();
        > 68 | 		await policyTechDocumentPage.selectWriterCheckbox('One, Writer');
             | 		                             ^
          69 | 		await policyTechDocumentPage.clickSubmitToWritersButton();
          70 | 		await expect(
          71 | 			policyTechDocumentPage.successPopupText,
    
            at PolicyTechDocumentPage.selectWriterCheckbox (/tests/tests/PageObjectModels/PolicyTech/ContentWindows/content.ts:119:58)
            at /tests/tests/e2etests/draftandcollaborationshould.spec.ts:68:32
    
        attachment #1: trace (application/zip) ---------------------------------------------------------
        test-results/e2etests-draftandcollaborationshould-Collaboration-Document-Send-Draft-Document-To-Writers-webkit/trace.zip
        Usage:
    
            npx playwright show-trace test-results/e2etests-draftandcollaborationshould-Collaboration-Document-Send-Draft-Document-To-Writers-webkit/trace.zip
    
        ------------------------------------------------------------------------------------------------
    
      3) [webkit] โ€บ e2etests/reviewandapprovalshould.spec.ts:41:2 โ€บ Review Document2 โ€บ Send Document To Review 
    
        locator.click: Target closed
        =========================== logs ===========================
          waiting for frame "iframe[name="Frame_PPMPopupIFrame"]"
          selector resolved to visible <iframe tabindex="0" role="document" id="Frame_PPMPopupIโ€ฆ></iframe>
        waiting for selector "iframe[name="Frame_PPMPopupIFrame"] >> control=enter-frame >> id=SendToolbarButton"
          selector resolved to visible <input value="Save" type="button" id="SendToolbarButtonโ€ฆ/>
        attempting click action
          waiting for element to be visible, enabled and stable
        ============================================================
    
          19 | 	await policyTechDocumentPage.clickContentTopMenuMoreButton();
          20 | 	await policyTechDocumentPage.clickSendToDraftButton();
        > 21 | 	await policyTechDocumentPage.clickSendToDraftSaveButton();
             | 	                             ^
          22 | 	await policyTechDocumentPage.clickResultsPopupOkButton();
          23 | 	await policyTechDocumentPage.clickContentTopMenuMoreButton();
          24 | 	await policyTechDocumentPage.clickContentTopMenuArchiveButton();
    
            at PolicyTechDocumentPage.clickSendToDraftSaveButton (/tests/tests/PageObjectModels/PolicyTech/ContentWindows/content.ts:155:36)
            at /tests/tests/e2etests/reviewandapprovalshould.spec.ts:21:31
    
        attachment #1: trace (application/zip) ---------------------------------------------------------
        test-results/e2etests-reviewandapprovalshould-Review-Document2-Send-Document-To-Review-webkit/trace.zip
        Usage:
    
            npx playwright show-trace test-results/e2etests-reviewandapprovalshould-Review-Document2-Send-Document-To-Review-webkit/trace.zip
    
        ------------------------------------------------------------------------------------------------
    
      Slow test file: [webkit] โ€บ e2etests/reviewandapprovalshould.spec.ts (35s)
      Slow test file: [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts (32s)
      Consider splitting slow test files to speed up parallel execution
    
      3 failed
        [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:37:2 โ€บ Draft Document โ€บ Save New Document 
        [webkit] โ€บ e2etests/draftandcollaborationshould.spec.ts:54:2 โ€บ Collaboration Document โ€บ Send Draft Document To Writers 
        [webkit] โ€บ e2etests/reviewandapprovalshould.spec.ts:41:2 โ€บ Review Document2 โ€บ Send Document To Review 
    
    browser-webkit P3-collecting-feedback v1.29 
    opened by eatonjl 35
  • [TestRunner] tsconfig, babel, tsx, esm metabug

    [TestRunner] tsconfig, babel, tsx, esm metabug

    Module resolver issue extracted as https://github.com/microsoft/playwright/issues/7066.

    https://github.com/microsoft/playwright/issues/7013 https://github.com/microsoft/playwright/issues/7037 https://github.com/microsoft/playwright/issues/7041 https://github.com/microsoft/playwright/issues/7042 https://github.com/microsoft/playwright/issues/7142 https://github.com/microsoft/playwright/issues/7148 https://github.com/microsoft/playwright/issues/7294 https://github.com/microsoft/playwright/issues/7855

    P3-collecting-feedback feature-test-runner 
    opened by pavelfeldman 35
  • [BUG] Node.js 16 results in DeprecationWarning: Use of deprecated folder mapping

    [BUG] Node.js 16 results in DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field with file import

    Current exports syntax is not compatible with node 15.

    (node:12200) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field module resolution of the package at C:\Users\zdm\.node_modules\playwright-chromium\package.json.
    Update this package.json to use a subpath pattern like "./*".
    

    You need to update to the new rules or remove this section.

    New rules should looks like this:

    "exports": {
        ".": {
          "import": "./index.mjs",
          "require": "./index.js"
        },
        "./*": "./*.js"
      },
    
    opened by zdm 28
  • [BUG] Cannot run Playwright via shell from IIS

    [BUG] Cannot run Playwright via shell from IIS

    Context:

    • Playwright Version: 1.8.0
    • Operating System: Windows
    • Node.js version: 12.18.3
    • Browser: Chromium
    • Extra: IIS 8

    Code Snippet

    const playwright = require('playwright');
    
    (async () => {
      const browser = await playwright.chromium.launch();
      // ...
    })();
    

    Describe the bug

    In IIS 8, I'm shelling out from PHP to run "node index.js", but I'm getting the below fatal error.

    It looks like an issue related to DPAPI, so I tried setting IIS to load a user profile, but that didn't make a difference. I've read through the Chromium source code a bit, but I'm not sure how the problem traces back.

    It's worth noting that replacing Playwright with Puppeteer solved the problem. Puppeteer has no problem. It looks like Playwright uses a newer version of Chromium than Puppeteer, so that may be related, or it may be that Playwright is enabling/disabling a switch that Puppeteer doesn't.

    ERROR: Access denied
    (node:8524) UnhandledPromiseRejectionWarning: browserType.launch: Protocol error (Browser.getVersion): Browser closed.
    ==================== Browser output: ====================
    <launching> C:\\opt\\playwright\\node_modules\\playwright\\.local-browsers\\chromium-844399\\chrome-win\\chrome.exe --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=TranslateUI,BlinkGenPropertyTrees,ImprovedCookieControls,SameSiteByDefaultCookies,LazyFrameLoading --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --user-data-dir=C:\\Windows\\TEMP\\playwright_chromiumdev_profile-bamqjN --remote-debugging-pipe --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --no-startup-window
    <launched> pid=5504
    [err] [0128/124939.752:ERROR:os_crypt_win.cc(70)] Failed to encrypt: The system cannot find the file specified. (0x2)
    [err] [0128/124939.752:FATAL:headless_browser_main_parts.cc(103)] Check failed: OSCrypt::Init(local_state_.get()). 
    [err] Backtrace:
    [err] 	IsSandboxedProcess [0x000007FE6F5B6362+709650]
    [err] 	IsSandboxedProcess [0x000007FE6F5392F2+197538]
    [err] 	IsSandboxedProcess [0x000007FE6F548468+259352]
    [err] 	IsSandboxedProcess [0x000007FE6F5493A0+263248]
    [err] 	RelaunchChromeBrowserWithNewCommandLineIfNeeded [0x000007FE70C63F93+11967571]
    [err] 	RelaunchChromeBrowserWithNewCommandLineIfNeeded [0x000007FE70C63CFD+11966909]
    [err] 	ovly_debug_event [0x000007FE6DB44DB9+15214521]
    [err] 	ovly_debug_event [0x000007FE6DF04CF7+19146487]
    [err] 	ovly_debug_event [0x000007FE6DB43B05+15209733]
    [err] 	ovly_debug_event [0x000007FE6DB4681E+15221278]
    [err] 	IsSandboxedProcess [0x000007FE6FFFB7E7+11479191]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F4CEDF3+9454995]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F4CFC12+9458610]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F4CF88F+9457711]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F4CE77D+9453341]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F4CEAFA+9454234]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F508639+9690585]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F5084FB+9690267]
    [err] 	CrashForExceptionInNonABICompliantCodeRange [0x000007FE6F5082F7+9689751]
    [err] 	ChromeMain [0x000007FE6CCC1238+408]
    [err] 	Ordinal0 [0x000007F6C1F426C8+9928]
    [err] 	Ordinal0 [0x000007F6C1F41A41+6721]
    [err] 	GetHandleVerifier [0x000007F6C2089222+898850]
    [err] 	BaseThreadInitThunk [0x000007FE9E8C1652+26]
    [err] 	RtlUserThreadStart [0x000007FEA10E91B1+33]
    [err] 
    
    browser-chromium P1-resolve-asap 
    opened by minusdavid 28
  • [Feature] Record network requests and save them as ready-to-use mocks

    [Feature] Record network requests and save them as ready-to-use mocks

    I'm using playwright for integration tests. And I can't have a full environment for testing. So I mock api requests and test against them.

    When I saw https://github.com/microsoft/playwright-cli/pull/194 this flow for authentication (which is super helpful, thank you), I thought it would be a great idea to generate code for network requests in a file and use them in specific tests (test by test basis in it("...") or beforeEach depending on the scenario.

    In this case, I see it like so:

    • Adding an option to the cli to save network requests to a given file (file name) like this npx playwright-cli --save-network-requests=flow_1_requests.json codegen
    • Adding an API method in playwright to use a mock file or multiple files. This would allow to overwrite previous mocks if they are defined in two files. playwright.useMockFiles(context, ['path/to/flow_1_requests.json', 'path/to/flow_2_requests.json']). It takes the context and paths to mock files.

    Same as https://github.com/microsoft/playwright-cli/issues/196

    P3-collecting-feedback feature-trace 
    opened by haikyuu 28
  • [Feature] Add path params to request options

    [Feature] Add path params to request options

    Desired behavior Playwright to support both query and path parameters:

    const capitalResponse = await request.get('https://restcountries.com/v3.1/name/{name}', {
            pathParams: {
                'name': 'denmark'
            },
            queryParams: {
                'fields': 'capital,languages',
            }
        });
    

    Formed url:

    https://restcountries.com/v3.1/name/denmark?fields=capital,languages
    

    This feature will make it easier to move all the test data logic inside the call method itself, rather than forming the url with parameters in a previous step.

    Current behavior: params in the request options are query parameter

    const capitalResponse = await request.get('https://restcountries.com/v3.1/name/denmark', {
            params: {
                "fields": 'capital,languages',
            }
        });
    

    Formed url:

    https://restcountries.com/v3.1/name/denmark?fields=capital,languages
    
    opened by irharrier2 0
  • [BUG] Docs give misleading information about CircleCI that breaks components tests

    [BUG] Docs give misleading information about CircleCI that breaks components tests

    Context:

    • Playwright Version: next (both in latest)
    • Operating System: Circle CI - mcr.microsoft.com/playwright:v1.29.0-focal
    • Node.js version: What's in mcr.microsoft.com/playwright:v1.29.0-focal
    • Browser: All
    • Extra: CI

    Code Snippet

    This line in the docs that suggest the NODE_ENV=development is needed in CI is misleading:

    1. It works without it
    2. It's actually fails react component build with vite 4

    Describe the bug

    NODE_ENV=development causes tests with @playwright/experimental-ct-react to timeout due to wrong complication. Because docs suggest to do that in CI, it causes error that hard to link to wrong docs config

    opened by oriSomething 0
  • [BUG] Can't run tests on Azure agent

    [BUG] Can't run tests on Azure agent "Executable doesn't exist "

    Context:

    • Playwright Version: 1.28.1
    • Operating System: Azure self-hosted agent (Windows)
    • Node.js version:18.12.1
    • Browser: Chromium
    • Extra: [any specific details about your environment]

    Code Snippet image image image image image

    Describe the bug Tests are running fine locally, but I pushed repo to Azure DevOps Repos and tried to run them in Azure DevOps Pipelines. Run fails with info that:

    browserType.launch: Executable doesn't exist at C:\Users\tfsbuild\AppData\Local\ms-playwright\chromium-1033\chrome-win\chrome.exe

    and: image

    I'm doing those 3 things:

    1. Instaling dependencies by: npm install
    2. As advised: running npx playwright install
    3. running tests by: npx playwright test

    But it still complains about Chromium, any tips on how to solve that?

    Add any other details about the problem here.

    opened by lucasbit 0
  • [Question] Missing snapshots not generated for all projects

    [Question] Missing snapshots not generated for all projects

    When running visual regression with Playwright, it is failing to update all missing snapshots for each project defined in the configuration file (See configuration below).

    import { type PlaywrightTestConfig, devices } from '@playwright/test';
    
    import { baseConfig } from '../../playwright.config.base';
    
    const config: PlaywrightTestConfig = {
      ...baseConfig,
      /* Run tests in files in parallel */
      fullyParallel: true,
      /* Fail the build on CI if you accidentally left test.only in the source code. */
      forbidOnly: !!process.env.CI,
      /* Retry on CI only */
      retries: process.env.CI ? 2 : 0,
      /* Reporter to use. */
      reporter: process.env.CI ? 'dot' : 'html',
      use: {
        ...baseConfig.use,
        screenshot: 'only-on-failure',
      }, 
      /* Configuration for visual regression checks */
      updateSnapshots: "missing",
      expect: {
        toHaveScreenshot: {
          threshold: 0.2,
          animations: "disabled"
        }
      },
      projects: [
        {
          name: 'chromium',
          use: {
            ...devices['Desktop Chrome'],
          },
        },
    
        {
          name: 'firefox',
          use: {
            ...devices['Desktop Firefox'],
          },
        },
    
        {
          name: 'webkit',
          use: {
            ...devices['Desktop Safari'],
          },
        },
    
        /* Test against mobile viewports. */
        {
          name: 'Mobile Chrome',
          use: {
            ...devices['Pixel 5'],
          },
        },
        {
          name: 'Mobile Safari',
          use: {
            ...devices['iPhone 12'],
          },
        },
      ],
    };
    
    export default config;
    

    When running my tests (where no screenshots currently exist) only a small subset of the missing screenshots are actually updated. The other projects fail to have their missing screenshots captured as each tests fails with the message "Test was interrupted." image You can see that many tests ran for a few ms before being interrupted, or did not start at all image

    However if I set the updateSnapshots value to "all" and again, delete all of the screenshots from the previous run so that we are in the same starting state, then all 10 screenshots get written as expected image

    I would expect that updateSnapshots value being set to "missing" would still run each project I have defined and capture all 10 screenshots, however this does not seem to be the case.

    Is this possibly a bug, or have I missed something obvious?

    opened by Danphillipz 0
  • [BUG] Infinite waiting for resolving waitForLoadState('networkidle')

    [BUG] Infinite waiting for resolving waitForLoadState('networkidle')

    Context:

    • Playwright Version: 1.29.1
    • Operating System: Mac
    • Node.js version: 16.13.0
    • Browser: Chromium

    With waitForLoadState('networkidle') inside the Promise.all, playwright is waiting until timeout even though no request is sent. Noticed it in my app, but I was able to reproduce it with the example page I passed in the code.

    Code Snippet

    test('test', async ({ page }) => {
      await page.goto('https://practice.automationtesting.in/');
      await Promise.all([page.waitForLoadState('networkidle')]);
      await page.waitForTimeout(5000);
    });
    
    opened by gamesterr 0
  • Should Playwright support sources with the mts extension?

    Should Playwright support sources with the mts extension?

    Should Playwright support sources with the mts extension? I am using the new TypeScript esm support in the test pipeline but cannot switch the overall project to esm.

    opened by doberkofler 0
Releases(v1.29.1)
  • v1.29.1(Dec 21, 2022)

    Highlights

    https://github.com/microsoft/playwright/issues/18928 - [BUG] Electron firstWindow times out after upgrading to 1.28.0 https://github.com/microsoft/playwright/issues/19246 - [BUG] Electron firstWindow times out after upgrading to 1.28.1 https://github.com/microsoft/playwright/issues/19412 - [REGRESSION]: 1.28 does not work with electron-serve anymore. https://github.com/microsoft/playwright/issues/19540 - [BUG] electron.app.getAppPath() returns the path one level higher if you run electron pointing to the directory https://github.com/microsoft/playwright/issues/19548 - [REGRESSION]: Ubuntu 18 LTS not supported anymore

    Browser Versions

    • Chromium 109.0.5414.46
    • Mozilla Firefox 107.0
    • WebKit 16.4

    This version was also tested against the following stable channels:

    • Google Chrome 108
    • Microsoft Edge 108
    Source code(tar.gz)
    Source code(zip)
  • v1.29.0(Dec 16, 2022)

    New APIs

    • New method route.fetch() and new option json for route.fulfill():

      await page.route('**/api/settings', async route => {
        // Fetch original settings.
        const response = await route.fetch();
      
        // Force settings theme to a predefined value.
        const json = await response.json();
        json.theme = 'Solorized';
      
        // Fulfill with modified data.
        await route.fulfill({ json });
      });
      
    • New method locator.all() to iterate over all matching elements:

      // Check all checkboxes!
      const checkboxes = page.getByRole('checkbox');
      for (const checkbox of await checkboxes.all())
        await checkbox.check();
      
    • Locator.selectOption matches now by value or label:

      <select multiple>
        <option value="red">Red</div>
        <option value="green">Green</div>
        <option value="blue">Blue</div>
      </select>
      
      await element.selectOption('Red');
      
    • Retry blocks of code until all assertions pass:

      await expect(async () => {
        const response = await page.request.get('https://api.example.com');
        await expect(response).toBeOK();
      }).toPass();
      

      Read more in our documentation.

    • Automatically capture full page screenshot on test failure:

      // playwright.config.ts
      import type { PlaywrightTestConfig } from '@playwright/test';
      
      const config: PlaywrightTestConfig = {
        use: {
          screenshot: {
            mode: 'only-on-failure',
            fullPage: true,
          }
        }
      };
      
      export default config;
      

    Miscellaneous

    Browser Versions

    • Chromium 109.0.5414.46
    • Mozilla Firefox 107.0
    • WebKit 16.4

    This version was also tested against the following stable channels:

    • Google Chrome 108
    • Microsoft Edge 108
    Source code(tar.gz)
    Source code(zip)
  • v1.28.1(Nov 23, 2022)

    Highlights

    This patch release includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/18928 - [BUG] Electron firstWindow times out after upgrading to 1.28.0 https://github.com/microsoft/playwright/issues/18920 - [BUG] [expanded=false] in role selector returns elements without aria-expanded attribute https://github.com/microsoft/playwright/issues/18865 - [BUG] regression in killing web server process in 1.28.0

    Browser Versions

    • Chromium 108.0.5359.29
    • Mozilla Firefox 106.0
    • WebKit 16.4

    This version was also tested against the following stable channels:

    • Google Chrome 107
    • Microsoft Edge 107
    Source code(tar.gz)
    Source code(zip)
  • v1.28.0(Nov 16, 2022)

    Playwright Tools

    • Record at Cursor in VSCode. You can run the test, position the cursor at the end of the test and continue generating the test.
    New VSCode Extension
    • Live Locators in VSCode. You can hover and edit locators in VSCode to get them highlighted in the opened browser.
    • Live Locators in CodeGen. Generate a locator for any element on the page using "Explore" tool.
    Locator Explorer
    • Codegen and Trace Viewer Dark Theme. Automatically picked up from operating system settings.
    Dark Theme

    Test Runner

    New APIs

    Browser Versions

    • Chromium 108.0.5359.29
    • Mozilla Firefox 106.0
    • WebKit 16.4

    This version was also tested against the following stable channels:

    • Google Chrome 107
    • Microsoft Edge 107
    Source code(tar.gz)
    Source code(zip)
  • v1.27.1(Oct 12, 2022)

    Highlights

    This patch release includes the following bug fixes:

    https://github.com/microsoft/playwright/pull/18010 - fix(generator): generate nice locators for arbitrary selectors https://github.com/microsoft/playwright/pull/17999 - chore: don't fail on undefined video/trace https://github.com/microsoft/playwright/issues/17955 - [Question] Github Actions test compatibility check failed mitigation? https://github.com/microsoft/playwright/issues/17960 - [BUG] Codegen 1.27 creates NUnit code that does not compile https://github.com/microsoft/playwright/pull/17952 - fix: fix typo in treeitem role typing

    Browser Versions

    • Chromium 107.0.5304.18
    • Mozilla Firefox 105.0.1
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 106
    • Microsoft Edge 106
    Source code(tar.gz)
    Source code(zip)
  • v1.27.0(Oct 7, 2022)

    Locators

    With these new APIs, inspired by Testing Library, writing locators is a joy:

    await page.getByLabel('User Name').fill('John');
    
    await page.getByLabel('Password').fill('secret-password');
    
    await page.getByRole('button', { name: 'Sign in' }).click();
    
    await expect(page.getByText('Welcome, John!')).toBeVisible();
    

    All the same methods are also available on Locator, FrameLocator and Frame classes.

    Other highlights

    • workers option in the playwright.config.ts now accepts a percentage string to use some of the available CPUs. You can also pass it in the command line:

      npx playwright test --workers=20%
      
    • New options host and port for the html reporter.

      reporters: [['html', { host: 'localhost', port: '9223' }]]
      
    • New field FullConfig.configFile is available to test reporters, specifying the path to the config file if any.

    • As announced in v1.25, Ubuntu 18 will not be supported as of Dec 2022. In addition to that, there will be no WebKit updates on Ubuntu 18 starting from the next Playwright release.

    Behavior Changes

    • expect(locator).toHaveAttribute(name, value, options) with an empty value does not match missing attribute anymore. For example, the following snippet will succeed when button does not have a disabled attribute.

      await expect(page.getByRole('button')).toHaveAttribute('disabled', '');
      
    • Command line options --grep and --grep-invert previously incorrectly ignored grep and grepInvert options specified in the config. Now all of them are applied together.

    • JSON reporter path resolution is performed relative to the config directory instead of the current working directory:

      ["json", { outputFile: "./test-results/results.json" }]]
      

    Browser Versions

    • Chromium 107.0.5304.18
    • Mozilla Firefox 105.0.1
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 106
    • Microsoft Edge 106
    Source code(tar.gz)
    Source code(zip)
  • v1.26.1(Sep 27, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/17500 - [BUG] No tests found using the test explorer - pw/[email protected]

    Browser Versions

    • Chromium 106.0.5249.30
    • Mozilla Firefox 104.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 105
    • Microsoft Edge 105
    Source code(tar.gz)
    Source code(zip)
  • v1.26.0(Sep 20, 2022)

    Assertions

    Other Highlights

    • New option maxRedirects for apiRequestContext.get(url[, options]) and others to limit redirect count.
    • New command-line flag --pass-with-no-tests that allows the test suite to pass when no files are found.
    • New command-line flag --ignore-snapshots to skip snapshot expectations, such as expect(value).toMatchSnapshot() and expect(page).toHaveScreenshot().

    Behavior Change

    A bunch of Playwright APIs already support the waitUntil: 'domcontentloaded' option. For example:

    await page.goto('https://playwright.dev', {
      waitUntil: 'domcontentloaded',
    });
    

    Prior to 1.26, this would wait for all iframes to fire the DOMContentLoaded event.

    To align with web specification, the 'domcontentloaded' value only waits for the target frame to fire the 'DOMContentLoaded' event. Use waitUntil: 'load' to wait for all iframes.

    Browser Versions

    • Chromium 106.0.5249.30
    • Mozilla Firefox 104.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 105
    • Microsoft Edge 105
    Source code(tar.gz)
    Source code(zip)
  • v1.25.2(Sep 7, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/16937 - [REGRESSION]: session storage failing >= 1.25.0 in firefox https://github.com/microsoft/playwright/issues/16955 - Not using channel on config file when Show and Reuse browser is checked

    Browser Versions

    • Chromium 105.0.5195.19
    • Mozilla Firefox 103.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 104
    • Microsoft Edge 104
    Source code(tar.gz)
    Source code(zip)
  • v1.25.1(Aug 23, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/16319 - [BUG] webServer.command esbuild fails with ESM and Yarn https://github.com/microsoft/playwright/issues/16460 - [BUG] Component test fails on 2nd run when SSL is used https://github.com/microsoft/playwright/issues/16665 - [BUG] custom selector engines don't work when running in debug mode

    Browser Versions

    • Chromium 105.0.5195.19
    • Mozilla Firefox 103.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 104
    • Microsoft Edge 104
    Source code(tar.gz)
    Source code(zip)
  • v1.25.0(Aug 11, 2022)

    VSCode Extension

    • New Playwright actions view

      Playwright actions
    • Pick selector You can pick selector right from a live page, before or after running a test

      Pick selector
    • Record new test Start recording where you left off with the new 'Record new test' feature.

    • Show & reuse browser Watch your tests running live & keep devtools open. Develop while continuously running tests.

    extension screenshot

    Test Runner

    • test.step(title, body) now returns the value of the step function:

      test('should work', async ({ page }) => {
          const pageTitle = await test.step('get title', async () => {
              await page.goto('https://playwright.dev');
              return await page.title();
          });
          console.log(pageTitle);
      });
      
    • Added test.describe.fixme(title, callback).

    • New 'interrupted' test status.

    • Enable tracing via CLI flag: npx playwright test --trace=on.

    • New property testCase.id that can be use in reporters as a history ID.

    Announcements

    • ๐ŸŽ We now ship Ubuntu 22.04 Jammy Jellyfish docker image: mcr.microsoft.com/playwright:v1.25.0-jammy.
    • ๐Ÿชฆ This is the last release with macOS 10.15 support (deprecated as of 1.21).
    • ๐Ÿชฆ This is the last release with Node.js 12 support, we recommend upgrading to Node.js LTS (16).
    • โš ๏ธ Ubuntu 18 is now deprecated and will not be supported as of Dec 2022.

    Browser Versions

    • Chromium 105.0.5195.19
    • Mozilla Firefox 103.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 104
    • Microsoft Edge 104
    Source code(tar.gz)
    Source code(zip)
  • v1.24.2(Jul 29, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/15977 - [BUG] test.use of storage state regression in 1.24

    Browser Versions

    • Chromium 104.0.5112.48
    • Mozilla Firefox 102.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.24.1(Jul 26, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/15898 - [BUG] Typescript error: The type for webServer config property (TestConfigWebServer) is not typed correctly https://github.com/microsoft/playwright/issues/15913 - [BUG] hooksConfig is required for mount fixture https://github.com/microsoft/playwright/issues/15932 - [BUG] - Install MS Edge on CI Fails

    Browser Versions

    • Chromium 104.0.5112.48
    • Mozilla Firefox 102.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.24.0(Jul 21, 2022)

    ๐ŸŒ Multiple Web Servers in playwright.config.ts

    Launch multiple web servers, databases, or other processes by passing an array of configurations:

    // playwright.config.ts
    import type { PlaywrightTestConfig } from '@playwright/test';
    const config: PlaywrightTestConfig = {
      webServer: [
        {
          command: 'npm run start',
          port: 3000,
          timeout: 120 * 1000,
          reuseExistingServer: !process.env.CI,
        },
        {
          command: 'npm run backend',
          port: 3333,
          timeout: 120 * 1000,
          reuseExistingServer: !process.env.CI,
        }
      ],
      use: {
        baseURL: 'http://localhost:3000/',
      },
    };
    export default config;
    

    ๐Ÿ‚ Debian 11 Bullseye Support

    Playwright now supports Debian 11 Bullseye on x86_64 for Chromium, Firefox and WebKit. Let us know if you encounter any issues!

    Linux support looks like this:

    | | Ubuntu 18.04 | Ubuntu 20.04 | Ubuntu 22.04 | Debian 11 | :--- | :---: | :---: | :---: | :---: | | Chromium | โœ… | โœ… | โœ… | โœ… | | WebKit | โœ… | โœ… | โœ… | โœ… | | Firefox | โœ… | โœ… | โœ… | โœ… |

    ๐Ÿ•ต๏ธ Anonymous Describe

    It is now possible to call test.describe(callback) to create suites without a title. This is useful for giving a group of tests a common option with test.use(options).

    test.describe(() => {
      test.use({ colorScheme: 'dark' });
    
      test('one', async ({ page }) => {
        // ...
      });
    
      test('two', async ({ page }) => {
        // ...
      });
    });
    

    ๐Ÿงฉ Component Tests Update

    Playwright 1.24 Component Tests introduce beforeMount and afterMount hooks. Use these to configure your app for tests.

    Vue + Vue Router

    For example, this could be used to setup App router in Vue.js:

    // src/component.spec.ts
    import { test } from '@playwright/experimental-ct-vue';
    import { Component } from './mycomponent';
    
    test('should work', async ({ mount }) => {
      const component = await mount(Component, {
        hooksConfig: {
          /* anything to configure your app */
        }
      });
    });
    
    // playwright/index.ts
    import { router } from '../router';
    import { beforeMount } from '@playwright/experimental-ct-vue/hooks';
    
    beforeMount(async ({ app, hooksConfig }) => {
      app.use(router);
    });
    

    React + Next.js

    A similar configuration in Next.js would look like this:

    // src/component.spec.jsx
    import { test } from '@playwright/experimental-ct-react';
    import { Component } from './mycomponent';
    
    test('should work', async ({ mount }) => {
      const component = await mount(<Component></Component>, {
        // Pass mock value from test into `beforeMount`.
        hooksConfig: {
          router: {
            query: { page: 1, per_page: 10 },
            asPath: '/posts'
          }
        }
      });
    });
    
    // playwright/index.js
    import router from 'next/router';
    import { beforeMount } from '@playwright/experimental-ct-react/hooks';
    
    beforeMount(async ({ hooksConfig }) => {
      // Before mount, redefine useRouter to return mock value from test.
      router.useRouter = () => hooksConfig.router;
    });
    

    Browser Versions

    • Chromium 104.0.5112.48
    • Mozilla Firefox 102.0
    • WebKit 16.0

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.23.4(Jul 16, 2022)

    Highlights

    This patch includes the following bug fix:

    https://github.com/microsoft/playwright/issues/15717 - [REGRESSION]: Suddenly stopped working despite nothing having changed (experimentalLoader.js:load did not call the next hook in its chain and did not explicitly signal a short circuit)

    Browser Versions

    • Chromium 104.0.5112.20
    • Mozilla Firefox 100.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.23.3(Jul 13, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/15557 - [REGRESSION]: Event Listeners not being removed if same handler is used for different events

    Browser Versions

    • Chromium 104.0.5112.20
    • Mozilla Firefox 100.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.23.2(Jul 7, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/15273 - [BUG] LaunchOptions config has no effect after update to v1.23.0 https://github.com/microsoft/playwright/issues/15351 - [REGRESSION]: Component testing project does not compile anymore https://github.com/microsoft/playwright/issues/15431 - [BUG] Regression: page.on('console') is ignored in 1.23

    Browser Versions

    • Chromium 104.0.5112.20
    • Mozilla Firefox 100.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.23.1(Jun 30, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/15219 - [REGRESSION]: playwright-core 1.23.0 issue with 'TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument'

    Browser Versions

    • Chromium 104.0.5112.20
    • Mozilla Firefox 100.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 103
    • Microsoft Edge 103
    Source code(tar.gz)
    Source code(zip)
  • v1.23.0(Jun 27, 2022)

    Playwright v1.23 updates

    Network Replay

    Now you can record network traffic into a HAR file and re-use the data in your tests.

    To record network into HAR file:

    npx playwright open --save-har=github.har.zip https://github.com/microsoft
    

    Alternatively, you can record HAR programmatically:

    const context = await browser.newContext({
      recordHar: { path: 'github.har.zip' }
    });
    // ... do stuff ...
    await context.close();
    

    Use the new methods page.routeFromHAR() or browserContext.routeFromHAR() to serve matching responses from the HAR file:

    await context.routeFromHAR('github.har.zip');
    

    Read more in our documentation.

    Advanced Routing

    You can now use route.fallback() to defer routing to other handlers.

    Consider the following example:

    // Remove a header from all requests.
    test.beforeEach(async ({ page }) => {
      await page.route('**/*', route => {
        const headers = route.request().headers();
        delete headers['if-none-match'];
        route.fallback({ headers });
      });
    });
    
    test('should work', async ({ page }) => {
      await page.route('**/*', route => {
        if (route.request().resourceType() === 'image')
          route.abort();
        else
          route.fallback();
      });
    });
    

    Note that the new methods page.routeFromHAR() and browserContext.routeFromHAR() also participate in routing and could be deferred to.

    Web-First Assertions Update

    Component Tests Update

    Read more about component testing with Playwright.

    Miscellaneous

    • If there's a service worker that's in your way, you can now easily disable it with a new context option serviceWorkers:
      // playwright.config.ts
      export default {
        use: {
          serviceWorkers: 'block',
        }
      }
      
    • Using .zip path for recordHar context option automatically zips the resulting HAR:
      const context = await browser.newContext({
        recordHar: {
          path: 'github.har.zip',
        }
      });
      
    • If you intend to edit HAR by hand, consider using the "minimal" HAR recording mode that only records information that is essential for replaying:
      const context = await browser.newContext({
        recordHar: {
          path: 'github.har.zip',
          mode: 'minimal',
        }
      });
      
    • Playwright now runs on Ubuntu 22 amd64 and Ubuntu 22 arm64. We also publish new docker image mcr.microsoft.com/playwright:v1.23.0-focal.

    โš ๏ธ Breaking Changes โš ๏ธ

    WebServer is now considered "ready" if request to the specified port has any of the following HTTP status codes:

    • 200-299
    • 300-399 (new)
    • 400, 401, 402, 403 (new)
    Source code(tar.gz)
    Source code(zip)
  • v1.22.2(May 21, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/14254 - [BUG] focus() function in version 1.22 closes dropdown (not of select type) instead of just focus on the option

    Browser Versions

    • Chromium 102.0.5005.40
    • Mozilla Firefox 99.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 101
    • Microsoft Edge 101
    Source code(tar.gz)
    Source code(zip)
  • v1.22.1(May 17, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/14186 - [BUG] expect.toHaveScreenshot() generates an argument error

    Browser Versions

    • Chromium 102.0.5005.40
    • Mozilla Firefox 99.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 101
    • Microsoft Edge 101
    Source code(tar.gz)
    Source code(zip)
  • v1.22.0(May 12, 2022)

    Introducing Component Testing (preview)

    Playwright Test can now test your React, Vue.js or Svelte components. You can use all the features of Playwright Test (such as parallelization, emulation & debugging) while running components in real browsers.

    component testing Component Tests (Preview)

    Here is what a typical component test looks like:

    // App.spec.tsx
    import { test, expect } from '@playwright/experimental-ct-react';
    import App from './App';
    
    // Let's test component in a dark scheme!
    test.use({ colorScheme: 'dark' });
    
    test('should render', async ({ mount }) => {
      const component = await mount(<App></App>);
    
      // As with any Playwright test, assert locator text.
      await expect(component).toContainText('React');
      // Or do a screenshot ๐Ÿš€
      await expect(component).toHaveScreenshot();
      // Or use any Playwright method
      await component.click();
    });
    

    Read more in our documentation.


    release update Playwright v1.22 updates

    Locators Update

    • Role selectors allow selecting elements by their ARIA role, ARIA attributes and accessible name.

      // Click a button with accessible name "log in"
      await page.click('role=button[name="log in"]')
      

      Read more in our documentation.

    • New locator.filter([options]) API to filter an existing locator

      const buttons = page.locator('role=button');
      // ...
      const submitButton = buttons.filter({ hasText: 'Submit' });
      await submitButton.click();
      

    Screenshots Update

    New web-first assertions expect(page).toHaveScreenshot() and expect(locator).toHaveScreenshot() that wait for screenshot stabilization and enhances test reliability.

    The new assertions has screenshot-specific defaults, such as:

    • disables animations
    • uses CSS scale option
    await page.goto('https://playwright.dev');
    await expect(page).toHaveScreenshot();
    

    The new expect(page).toHaveScreenshot() saves screenshots at the same location as expect(screenshot).toMatchSnapshot().

    Browser Versions

    • Chromium 102.0.5005.40
    • Mozilla Firefox 99.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 101
    • Microsoft Edge 101
    Source code(tar.gz)
    Source code(zip)
  • v1.21.1(Apr 18, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/pull/13597 - [BUG] fullyParallel created too many workers, slowing down test run https://github.com/microsoft/playwright/issues/13530 - [REGRESSION]: Pull request #12877 prevents the library from being used on any linux distro that is not Ubuntu

    Browser Versions

    • Chromium 101.0.4951.26
    • Mozilla Firefox 98.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 100
    • Microsoft Edge 100
    Source code(tar.gz)
    Source code(zip)
  • v1.21.0(Apr 12, 2022)

    release 1.21 Playwright v1.21 updates

    Highlights

    • New experimental role selectors that allow selecting elements by their ARIA role, ARIA attributes and accessible name.

      // Click a button with accessible name "log in"
      await page.click('role=button[name="log in"]')
      

      To use role selectors, make sure to pass PLAYWRIGHT_EXPERIMENTAL_FEATURES=1 environment variable:

      // playwright.config.js
      process.env.PLAYWRIGHT_EXPERIMENTAL_FEATURES = '1';
      module.exports = {
        /* ... */
      };
      

      Read more in our documentation.

    • New scale option in Page.screenshot for smaller sized screenshots.

    • New caret option in Page.screenshot to control text caret. Defaults to "hide".

    • New method expect.poll to wait for an arbitrary condition:

      // Poll the method until it returns an expected result.
      await expect.poll(async () => {
        const response = await page.request.get('https://api.example.com');
        return response.status();
      }).toBe(200);
      

      expect.poll supports most synchronous matchers, like .toBe(), .toContain(), etc. Read more in our documentation.

    Behavior Changes

    • ESM support when running TypeScript tests is now enabled by default. The PLAYWRIGHT_EXPERIMENTAL_TS_ESM env variable is no longer required.
    • The mcr.microsoft.com/playwright docker image no longer contains Python. Please use mcr.microsoft.com/playwright/python as a Playwright-ready docker image with pre-installed Python.
    • Playwright now supports large file uploads (100s of MBs) via Locator.setInputFiles API.

    Browser Versions

    • Chromium 101.0.4951.26
    • Mozilla Firefox 98.0.2
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 100
    • Microsoft Edge 100
    Source code(tar.gz)
    Source code(zip)
  • v1.20.2(Apr 1, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/13078 - [BUG] Extension required when importing other files with type="module" https://github.com/microsoft/playwright/issues/13099 - [BUG] beforeAll is called before each test (fullyParallel) https://github.com/microsoft/playwright/issues/13204 - [BUG] mask stalls the screenshot

    Browser Versions

    • Chromium 101.0.4921.0
    • Mozilla Firefox 97.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 99
    • Microsoft Edge 99
    Source code(tar.gz)
    Source code(zip)
  • v1.20.1(Mar 23, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/12711 - [REGRESSION] Page.screenshot hangs on some sites https://github.com/microsoft/playwright/issues/12807 - [BUG] Cookies get assigned before fulfilling a response https://github.com/microsoft/playwright/issues/12814 - [Question] how to use expect.any in playwright https://github.com/microsoft/playwright/issues/12821 - [BUG] Chromium: Cannot click, element intercepts pointer events https://github.com/microsoft/playwright/issues/12836 - [REGRESSION]: Tests not detected as ES module in v1.20 https://github.com/microsoft/playwright/issues/12862 - [Feature] Allow to use toMatchSnapshot for file formats other than txt (e.g. csv) https://github.com/microsoft/playwright/issues/12887 - [BUG] Locator.count() with _vue selector with Repro https://github.com/microsoft/playwright/issues/12940 - [BUG] npm audit - High Severity vulnerability in json5 package forcing to install Playwright 1.18.1 https://github.com/microsoft/playwright/issues/12974 - [BUG] Regression - chromium browser closes during test or debugging session on macos

    Browser Versions

    • Chromium 101.0.4921.0
    • Mozilla Firefox 97.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 99
    • Microsoft Edge 99
    Source code(tar.gz)
    Source code(zip)
  • v1.20.0(Mar 14, 2022)

    release-1.20 Playwright v1.20 updates

    Highlights

    • New options for methods page.screenshot(), locator.screenshot() and elementHandle.screenshot():

      • Option animations: "disabled" rewinds all CSS animations and transitions to a consistent state.
      • Option mask: Locator[] masks given elements, overlaying them with pink #FF00FF boxes.
    • expect().toMatchSnapshot() now supports anonymous snapshots: when snapshot name is missing, Playwright Test will generate one automatically:

      expect('Web is Awesome <3').toMatchSnapshot();
      
    • New maxDiffPixels and maxDiffPixelRatio options for fine-grained screenshot comparison using expect().toMatchSnapshot():

      expect(await page.screenshot()).toMatchSnapshot({
        maxDiffPixels: 27, // allow no more than 27 different pixels.
      });
      

      It is most convenient to specify maxDiffPixels or maxDiffPixelRatio once in TestConfig.expect.

    • Playwright Test now adds TestConfig.fullyParallel mode. By default, Playwright Test parallelizes between files. In fully parallel mode, tests inside a single file are also run in parallel. You can also use --fully-parallel command line flag.

      // playwright.config.ts
      export default {
        fullyParallel: true,
      };
      
    • TestProject.grep and TestProject.grepInvert are now configurable per project. For example, you can now configure smoke tests project using grep:

      // playwright.config.ts
      export default {
        projects: [
          {
            name: 'smoke tests',
            grep: /@smoke/,
          },
        ],
      };
      
    • Trace Viewer now shows API testing requests.

    • locator.highlight() visually reveals element(s) for easier debugging.

    Announcements

    • We now ship a designated Python docker image mcr.microsoft.com/playwright/python. Please switch over to it if you use Python. This is the last release that includes Python inside our javascript mcr.microsoft.com/playwright docker image.
    • v1.20 is the last release to receive WebKit update for macOS 10.15 Catalina. Please update MacOS to keep using latest & greatest WebKit!

    Browser Versions

    • Chromium 101.0.4921.0
    • Mozilla Firefox 97.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 99
    • Microsoft Edge 99
    Source code(tar.gz)
    Source code(zip)
  • v1.19.2(Feb 24, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/12091 - [BUG] playwright 1.19.0 generates more than 1 trace file per test https://github.com/microsoft/playwright/issues/12106 - [BUG] Error: EBUSY: resource busy or locked when using volumes in docker-compose with playwright 1.19.0 and mcr.microsoft.com/playwright:v1.15.0-focal

    Browser Versions

    • Chromium 100.0.4863.0
    • Mozilla Firefox 96.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 98
    • Microsoft Edge 98
    Source code(tar.gz)
    Source code(zip)
  • v1.19.1(Feb 16, 2022)

    Highlights

    This patch includes the following bug fixes:

    https://github.com/microsoft/playwright/issues/12075 - [Question] After update to 1.19 firefox fails to run https://github.com/microsoft/playwright/issues/12090 - [BUG] did something change on APIRequest/Response APIs ?

    Browser Versions

    • Chromium 100.0.4863.0
    • Mozilla Firefox 96.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 98
    • Microsoft Edge 98
    Source code(tar.gz)
    Source code(zip)
  • v1.19.0(Feb 11, 2022)

    release-1.19 Playwright v1.19 updates

    Playwright Test Updates

    Soft assertions

    Playwright Test v1.19 now supports soft assertions. Failed soft assertions do not terminate test execution, but mark the test as failed. Read more in our documentation.

    // Make a few checks that will not stop the test when failed...
    await expect.soft(page.locator('#status')).toHaveText('Success');
    await expect.soft(page.locator('#eta')).toHaveText('1 day');
    
    // ... and continue the test to check more things.
    await page.locator('#next-page').click();
    await expect.soft(page.locator('#title')).toHaveText('Make another order');
    

    Custom error messages

    You can now specify a custom error message as a second argument to the expect and expect.soft functions, for example:

    await expect(page.locator('text=Name'), 'should be logged in').toBeVisible();
    

    The error would look like this:

        Error: should be logged in
    
        Call log:
          - expect.toBeVisible with timeout 5000ms
          - waiting for selector "text=Name"
    
    
          2 |
          3 | test('example test', async({ page }) => {
        > 4 |   await expect(page.locator('text=Name'), 'should be logged in').toBeVisible();
            |                                                                  ^
          5 | });
          6 |
    

    Parallel mode in file

    By default, tests in a single file are run in order. If you have many independent tests in a single file, you can now run them in parallel with method: test.describe.configure:

    import { test } from '@playwright/test';
    
    test.describe.configure({ mode: 'parallel' });
    
    test('parallel 1', async () => {});
    test('parallel 2', async () => {});
    

    โš ๏ธ Potentially breaking change in Playwright Test Global Setup

    It is unlikely that this change will affect you, no action is required if your tests keep running as they did.

    We've noticed that in rare cases, the set of tests to be executed was configured in the global setup by means of the environment variables. We also noticed some applications that were post processing the reporters' output in the global teardown. If you are doing one of the two, learn more

    Locator Updates

    Locator now supports a has option that makes sure it contains another locator inside:

    await page.locator('article', {
      has: page.locator('.highlight'),
    }).locator('button').click();
    

    The snippet above will select article that has highlight in it and will press the button in it. Read more in locator documentation

    Other Updates

    Browser Versions

    • Chromium 100.0.4863.0
    • Mozilla Firefox 96.0.1
    • WebKit 15.4

    This version was also tested against the following stable channels:

    • Google Chrome 98
    • Microsoft Edge 98

    Source code(tar.gz)
    Source code(zip)
Owner
Microsoft
Open source projects and samples from Microsoft
Microsoft
A single tab web browser built with puppeteer. Also, no client-side JS. Viewport is streamed with MJPEG. For realz.

:tophat: A single tab web browser built with puppeteer. Also, no client-side JS. Viewport is streamed with MJPEG. For realz.

Cris 23 Dec 23, 2022
Simple JavaScript testing framework for browsers and node.js

A JavaScript Testing Framework Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any Ja

Jasmine 15.5k Jan 2, 2023
๐Ÿ”ฎ An easy-to-use JavaScript unit testing framework.

QUnit - A JavaScript Unit Testing Framework. QUnit is a powerful, easy-to-use, JavaScript unit testing framework. It's used by the jQuery project to t

QUnit 4k Jan 2, 2023
Simple interactive HTTP response mocker, useful for testing API callouts.

Simple interactive HTTP response mocker, useful for testing API callouts.

null 1 Jul 1, 2022
A Node.js tool to automate end-to-end web testing.

A Node.js tool to automate end-to-end web testing. Write tests in JS or TypeScript, run them and view results. Homepage โ€ข Documentation โ€ข FAQ โ€ข Suppor

Developer Express Inc. 9.5k Jan 9, 2023
Delightful JavaScript Testing.

?? Delightful JavaScript Testing ????โ€?? Developer Ready: A comprehensive JavaScript testing solution. Works out of the box for most JavaScript projec

Facebook 41k Jan 4, 2023
The goal of this app is to make user life easier while testing their own apps

Manual testing app The goal of this app is to make user life easier while testing their own apps. It is used to create the testing workflow, record te

null 1 Jan 2, 2023
Cypress Playback is a plugin and a set of commands that allows Cypress to automatically record responses to network requests made during a test run.

Cypress Playback ?? Automatically record and playback HTTP requests made in Cypress tests. Cypress Playback is a plugin and a set of commands that all

Oโ€™Reilly Media, Inc. 5 Dec 16, 2022
โ˜•๏ธ simple, flexible, fun javascript test framework for node.js & the browser

โ˜•๏ธ Simple, flexible, fun JavaScript test framework for Node.js & The Browser โ˜•๏ธ Links Documentation Release Notes / History / Changes Code of Conduct

Mocha 21.8k Dec 30, 2022
[unmaintained] DalekJS Base framework

DalekJS is not maintained any longer ?? We recommend TestCafรฉ for your automated browser testing needs. dalekjs DalekJS base framework Resources API D

DalekJS 703 Dec 9, 2022
E2E test framework for Angular apps

Protractor Protractor is an end-to-end test framework for Angular and AngularJS applications. Protractor is a Node.js program built on top of WebDrive

Angular 8.8k Jan 2, 2023
blanket.js is a simple code coverage library for javascript. Designed to be easy to install and use, for both browser and nodejs.

Blanket.js A seamless JavaScript code coverage library. FYI: Please note that this repo is not actively maintained If you're looking for a more active

Alex Seville 1.4k Dec 16, 2022
JSCover is a JavaScript Code Coverage Tool that measures line, branch and function coverage

JSCover - A JavaScript code coverage measurement tool. JSCover is an easy-to-use JavaScript code coverage measuring tool. It is an enhanced version of

null 392 Nov 20, 2022
Test runner based on Tape and Browserify

prova Node & Browser Test runner based on Tape and Browserify. Screencasts: node.gif, browser.gif, both.gif, headless browser Slides: slides.com/azer/

Azer Koรงulu 335 Oct 28, 2022
tap-producing test harness for node and browsers

tape tap-producing test harness for node and browsers example var test = require('tape'); test('timing test', function (t) { t.plan(2); t.eq

James Halliday 5.7k Dec 18, 2022
A new generation GUI automation framework for Web and Desktop Application Testing and Automation.

Clicknium-docs Clicknium is a new generation GUI automation framework for all types of applications. It provides easy and smooth developer experience

null 109 Dec 19, 2022
A testing focused Remix Stack, that integrates E2E & Unit testing with Playwright, Vitest, MSW and Testing Library. Driven by Prisma ORM. Deploys to Fly.io

Live Demo ยท Twitter A testing focused Remix Stack, that integrates E2E & Unit testing with Playwright, Vitest, MSW and Testing Library. Driven by Pris

Remix Stacks 18 Oct 31, 2022
Automagically bypass hcaptcha challenges with http api, with puppeteer, selenium, playwright browser automation scripts to bypass hCaptcha programmatically

Automagically bypass hcaptcha challenges with http api, with puppeteer, selenium, playwright browser automation scripts to bypass hCaptcha programmatically. For help you can message on discord server with the bellow link. You can also create an issue.

Shimul 199 Jan 2, 2023
Demo showcasing information leaks resulting from an IndexedDB same-origin policy violation in WebKit.

Safari 15 IndexedDB Leaks Description This demo showcases information leaks resulting from an IndexedDB same-origin policy violation in WebKit (a brow

FingerprintJS 101 Nov 5, 2022