Garry Taylor

Garry Taylor

1656302389

Playwright: A Framework for Web Testing and Automation

🎭 Playwright

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.

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

Looking for Playwright for Python, .NET, or Java?

Installation

Playwright has its own test runner for end-to-end tests, we call it Playwright Test.

Using init command

The easiest way to get started with Playwright Test is to run the init command.

# Run from your project's root directory
npm init playwright@latest
# Or create a new project
npm init playwright@latest new-project

This will create a configuration file, optionally add examples, a GitHub Action workflow and a first test example.spec.ts. You can now jump directly to writing assertions section.

Manually

Add dependency and install browsers.

npm i -D @playwright/test
# install supported browsers
npx playwright install

You can optionally install only selected browsers, see install browsers for more details. Or you can install no browsers at all and use existing browser channels.

Capabilities

Resilient β€’ No flaky tests

Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has rich set of introspection events. The combination of the two eliminate the need for artificial timeouts - primary cause of flaky tests.

Web-first assertions. Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met.

Tracing. Configure test retry strategy, capture execution trace, videos, screenshots to eliminate flakes.

No trade-offs β€’ No limits

Browsers run web content belonging to different origins in different processes. Playwright is aligned with the modern browsers architecture and runs tests out-of-process. This makes Playwright free of the typical in-process test runner limitations.

Multiple everything. Test scenarios that span multiple tabs, multiple origins and multiple users. Create scenarios with different contexts for different users and run them against your server, all in one test.

Trusted events. Hover elements, interact with dynamic controls, produce trusted events. Playwright uses real browser input pipeline indistinguishable from the real user.

Test frames, pierce Shadow DOM. Playwright selectors pierce shadow DOM and allow entering frames seamlessly.

Full isolation β€’ Fast execution

Browser contexts. Playwright creates a browser context for each test. Browser context is equivalent to a brand new browser profile. This delivers full test isolation with zero overhead. Creating a new browser context only takes a handful of milliseconds.

Log in once. Save the authentication state of the context and reuse it in all the tests. This bypasses repetitive log-in operations in each test, yet delivers full isolation of independent tests.

Powerful Tooling

Codegen. Generate tests by recording your actions. Save them into any language.

Playwright inspector. Inspect page, generate selectors, step through the test execution, see click points, explore execution logs.

Trace Viewer. Capture all the information to investigate the test failure. Playwright trace contains test execution screencast, live DOM snapshots, action explorer, test source and many more.

Looking for Playwright for TypeScript, JavaScript, Python, .NET, or Java?

Examples

To learn how to run these Playwright Test examples, check out our getting started docs.

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

Documentation | API reference

Download Details: 
Author: Microsoft
Source Code: https://github.com/Microsoft/playwright 
License: Apache-2.0 license
#playwright #test #testing 

Playwright: A Framework for Web Testing and Automation

Demo.Playwright: Various Testing Scenarios with Playwright

🎭 demo.playwright

This repo is used to demo various testing scenarios with Playwright 🎭, using the official test-runner and scripts authored in TypeScript.

The test.yml GitHub Action workflow is used to:

Run Playwright example tests

accessibility - runs accessibility checks against https://www.w3.org

android - runs a basic test using Android's WebView.

basic - basic tests to show interactions, element selectors, assertions, upload files, read a response, mock a response, and page object model (POM).

chrome-extension - basic test that gets a handle to the background page of Chrome extension.

drag-and-drop - runs example drag-and-drop test utilizing https://www.w3schools.com/html/html5_draganddrop.asp.

electron - runs a basic test for Electron application, controlling main electron process and working with Electron window.

fixtures - runs example tests utilizing test and worker fixtures.

github-api - uses GitHub API to test creation of a new repo, bug, and feature, then deletion of repo.

oauth - runs oauth tests for LinkedIn, Facebook, and Google, to login to https://courses.ultimateqa.com/users/sign_in.

performance - web performance tests using resource timing API, DevTools, and lighthouse, run against https://fastestwebsite.net

svgomg - End-to-end tests for SVGOMG! site, hosted at https://demo.playwright.dev/svgomg

todomvc - End-to-end tests for ToDoMVC site, hosted at https://demo.playwright.dev/todomvc

visual-comparison - visually compares snapshots with golden screenshots and text content for playwright.dev landing page.

Publish each HTML report to their respective directory

When the above tests are finished, the results are published to GitHub pages:

Configuration

The baseURL value for most tests is set as a workflow environment variable. This allows flexibility for the URL of the sites tested. By not hardcoding a URL in page.goTo('') we can simply pass baseURL without changing the test script e.g. test.site.com -> stage.site.com -> prod.site.com

Have a testing scenario you'd like to see included?

Please open an issue with details.

Author: MarcusFelling
Source Code: https://github.com/MarcusFelling/Demo.Playwright 
License: Apache-2.0 license

#node #playwright #demo #testing #typescript 

Demo.Playwright: Various Testing Scenarios with Playwright

Efficient Selenium Protocol Implementas Run Everything in Kubernetes

Moon

Moon is a commercial closed-source enterprise Selenium implementation using Kubernetes to launch browsers.

Moon Animation

Pricing Model

  • The only limitation that determines final Moon price is the total number of browser pods being run in parallel.
  • You can run up to 4 (four) parallel pods for free. Everything on top of free limit is paid as a subscription.
  • Detailed pricing information is available in respective documentation section.
  • To obtain a free evaluation license key email to sales@aerokube.com

Free Support

Features

The main idea behind Moon is to be easily installable and require zero maintenance.

One-command Installation

Having a running Kubernetes cluster and kubectl pointing to it you can launch free Moon cluster with this one-liner:

$ git clone https://github.com/aerokube/moon-deploy.git && cd moon-deploy && kubectl apply -f moon.yaml

To obtain Moon load balancer IP address use the following command:

$ kubectl get svc -n moon
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                         AGE
moon      LoadBalancer   10.63.242.109   104.154.161.58   4444:31894/TCP,8080:30625/TCP   1m

Now use the following Selenium URL in your code:

http://104.154.161.58:4444/wd/hub

We also provide detailed installation video.

Automatic Browser Management

Browsers

  • We maintain ready to use images for Firefox, Chrome, Opera and Android.
  • New browser versions are automatically accessible right after releases.

Scalability and Fault Tolerance

  • Your cluster size is automatically determined by Kubernetes depending on the load.
  • Moon is completely stateless and allows to run an unlimited number of replicas behind load balancer.
  • No additional configuration is required to add a new Moon replica.
  • User requests are not lost even in case of an accidental crash or downtime of the replica.

Efficient and Lightning Fast

  • Completely new Selenium protocol implementation using lightning fast Golang.
  • One Moon replica consumes 0.5 CPU and 512 Mb RAM maximum.
  • One Moon replica is able to work with thousands of running sessions.
  • No Selenium Grid components used.

Logs and Video

  • You can access live browser screen and logs for debugging purposes during test run.
  • Any browser session can be saved to a video file using desired codec, frame rate and screen size.
  • Logs and video files can be automatically uploaded to S3-compatible storage.

Complete Guide

Complete reference guide can be found at: http://aerokube.com/moon/latest/

Author: Aerokube
Source Code: https://github.com/aerokube/moon 
License: Apache-2.0 license

#node #selenium #kubernetes #openshift #playwright 

Efficient Selenium Protocol Implementas Run Everything in Kubernetes

ESLint Plugin for Your Playwright Testing Needs

ESLint Plugin Playwright 

ESLint plugin for your Playwright testing needs.

Installation

Yarn

yarn add -D eslint-plugin-playwright

NPM

npm install -D eslint-plugin-playwright

Usage

This plugin bundles two configurations to work with both @playwright/test or jest-playwright.

With Playwright test runner

{
  "extends": ["plugin:playwright/playwright-test"]
}

With Jest Playwright

{
  "extends": ["plugin:playwright/jest-playwright"]
}

Rules

missing-playwright-await πŸ”§

Identify false positives when async Playwright APIs are not properly awaited.

Example

Example of incorrect code for this rule:

expect(page).toMatchText('text');

test.step('clicks the button', async () => {
  await page.click('button');
});

Example of correct code for this rule:

await expect(page).toMatchText('text');

await test.step('clicks the button', async () => {
  await page.click('button');
});

Options

The rule accepts a non-required option which can be used to specify custom matchers which this rule should also warn about. This is useful when creating your own async expect matchers.

{
  "playwright/missing-playwright-await": [
    "error",
    { "customMatchers": ["toBeCustomThing"] }
  ]
}

no-page-pause

Prevent usage of page.pause().

Example

Example of incorrect code for this rule:

await page.click('button');
await page.pause();

Example of correct code for this rule:

await page.click('button');

no-element-handle

Disallow the creation of element handles with page.$ or page.$$.

Examples of incorrect code for this rule:

// Element Handle
const buttonHandle = await page.$('button');
await buttonHandle.click();

// Element Handles
const linkHandles = await page.$$('a');

Example of correct code for this rule:

const buttonLocator = page.locator('button');
await buttonLocator.click();

no-eval

Disallow usage of page.$eval and page.$$eval.

Examples of incorrect code for this rule:

const searchValue = await page.$eval('#search', (el) => el.value);

const divCounts = await page.$$eval(
  'div',
  (divs, min) => divs.length >= min,
  10
);

await page.$eval('#search', (el) => el.value);

await page.$$eval('#search', (el) => el.value);

Example of correct code for this rule:

await page.locator('button').evaluate((node) => node.innerText);

await page.locator('div').evaluateAll((divs, min) => divs.length >= min, 10);

no-focused-test

Disallow usage of .only() annotation

Examples of incorrect code for this rule:

test.only('focus this test', async ({ page }) => {});

test.describe.only('focus two tests', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

test.describe.parallel.only('focus two tests in parallel mode', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

test.describe.serial.only('focus two tests in serial mode', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

Examples of correct code for this rule:

test('this test', async ({ page }) => {});

test.describe('two tests', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

test.describe.parallel('two tests in parallel mode', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

test.describe.serial('two tests in serial mode', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

no-wait-for-timeout

Disallow usage of page.waitForTimeout().

Example of incorrect code for this rule:

await page.waitForTimeout(5000);

Examples of correct code for this rule:

// Use signals such as network events, selectors becoming visible and others instead.
await page.waitForLoadState();

await page.waitForUrl('/home');

await page.waitForFunction(() => window.innerWidth < 100);

no-skipped-test

Disallow usage of the .skip() annotation.

Examples of incorrect code for this rule:

test.skip('skip this test', async ({ page }) => {});

test.describe.skip('skip two tests', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

test.describe('skip test inside describe', () => {
  test.skip();
});

test.describe('skip test conditionally', async ({ browserName }) => {
  test.skip(browserName === 'firefox', 'Working on it');
});

Examples of correct code for this rule:

test('this test', async ({ page }) => {});

test.describe('two tests', () => {
  test('one', async ({ page }) => {});
  test('two', async ({ page }) => {});
});

no-force-option

Disallow usage of the { force: true } option.

Examples of incorrect code for this rule:

await page.locator('button').click({ force: true });

await page.locator('check').check({ force: true });

await page.locator('input').fill('something', { force: true });

Examples of correct code for this rule:

await page.locator('button').click();

await page.locator('check').check();

await page.locator('input').fill('something');

max-nested-describe

Enforces a maximum depth to nested .describe() calls. Useful for improving readability and parallelization of tests.

Uses a default max depth option of { "max": 5 }.

Examples of incorrect code for this rule (using defaults):

test.describe('level 1', () => {
  test.describe('level 2', () => {
    test.describe('level 3', () => {
      test.describe('level 4', () => {
        test.describe('level 5', () => {
          test.describe('level 6', () => {
            test('this test', async ({ page }) => {});
            test('that test', async ({ page }) => {});
          });
        });
      });
    });
  });
});

Examples of correct code for this rule (using defaults):

test.describe('first level', () => {
  test.describe('second level', () => {
    test('this test', async ({ page }) => {});
    test('that test', async ({ page }) => {});
  });
});

Options

The rule accepts a non-required option to override the default maximum nested describe depth (5).

{
  "playwright/max-nested-describe": ["error", { "max": 3 }]
}

no-conditional-in-test

Disallow conditional statements such as if, switch, and ternary expressions within tests.

Examples of incorrect code for this rule:

test('foo', async ({ page }) => {
  if (someCondition) {
    bar();
  }
});

test('bar', async ({ page }) => {
  switch (mode) {
    case 'single':
      generateOne();
      break;
    case 'double':
      generateTwo();
      break;
    case 'multiple':
      generateMany();
      break;
  }

  await expect(page.locator('.my-image').count()).toBeGreaterThan(0);
});

test('baz', async ({ page }) => {
  const hotkey =
    process.platform === 'linux' ? ['Control', 'Alt', 'f'] : ['Alt', 'f'];
  await Promise.all(hotkey.map((x) => page.keyboard.down(x)));

  expect(actionIsPerformed()).toBe(true);
});

Examples of correct code for this rule:

test.describe('my tests', () => {
  if (someCondition) {
    test('foo', async ({ page }) => {
      bar();
    });
  }
});

beforeEach(() => {
  switch (mode) {
    case 'single':
      generateOne();
      break;
    case 'double':
      generateTwo();
      break;
    case 'multiple':
      generateMany();
      break;
  }
});

test('bar', async ({ page }) => {
  await expect(page.locator('.my-image').count()).toBeGreaterThan(0);
});

const hotkey =
  process.platform === 'linux' ? ['Control', 'Alt', 'f'] : ['Alt', 'f'];

test('baz', async ({ page }) => {
  await Promise.all(hotkey.map((x) => page.keyboard.down(x)));

  expect(actionIsPerformed()).toBe(true);
});

Author: Playwright-community
Source Code: https://github.com/playwright-community/eslint-plugin-playwright 
License: MIT license

#node #eslint #jest #playwright 

ESLint Plugin for Your Playwright Testing Needs

Expect-playwright: Expect Utility Matcher Functions

expect-playwright

The Playwright test runner includes all the matchers in this repo plus many more to make testing your projects easy. This doesn't mean, that we stop with maintaining this package.


This library provides utility matchers for Jest in combination with Playwright. All of them are exposed on the expect object. You can use them either directly or invert them via the .not property like shown in a example below.

npm install -D expect-playwright

Usage

With Playwright test runner

To activate with the Playwright test runner, use expect.extend() in the config to add the expect-playwright matchers.

// playwright.config.ts
import { expect } from "@playwright/test"
import { matchers } from "expect-playwright"

expect.extend(matchers)

// ...

With Jest

To activate it in your Jest environment you have to include it in your configuration.

{
  "setupFilesAfterEnv": ["expect-playwright"]
}

Why do I need it

The Playwright API is great, but it is low level and not designed for integration testing. So this package tries to provide a bunch of utility functions to perform the common checks easier.

Example which should wait and compare the text content of a paragraph on the page.

// before
await page.waitForSelector("#foo")
const textContent = await page.$eval("#foo", (el) => el.textContent)
expect(textContent).stringContaining("my text")

// after by using expect-playwright
await expect(page).toMatchText("#foo", "my text")

But that's not all! Our matchers also work inside of iframes and accept an ElementHandle which targets an iframe element or a Frame obtained by calling element.contentFrame(). Not only that, but if you pass a promise, we will automatically resolve it for you!

// before
const element = await page.$("iframe")
const frame = await element.contentFrame()
await expect(frame).toBeChecked("#foo")

// after
await expect(page.$("iframe")).toBeChecked("#foo")

API documentation

toBeChecked

This function checks if a given element is checked.

You can do this via a selector on the whole page:

await expect(page).toBeChecked("#my-element")

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toBeChecked()

toBeDisabled

This function checks if a given element is disabled.

You can do this via a selector on the whole page:

await expect(page).toBeDisabled("#my-element")

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toBeDisabled()

toBeEnabled

This function checks if a given element is enabled.

You can do this via a selector on the whole page:

await expect(page).toBeEnabled("#my-element")

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toBeEnabled()

toHaveFocus

This function checks if a given element is focused.

You can do this via a selector on the whole page:

await expect(page).toHaveFocus("#foobar")

Or by passing a Playwright ElementHandle:

const element = await page.$("#foobar")
await expect(element).toHaveFocus()

toHaveSelector

This function waits as a maximum as the timeout exceeds for a given selector once it appears on the page.

await expect(page).toHaveSelector("#foobar")

When used with not, toHaveSelector will wait until the element is not visible or not attached. See the Playwright waitForSelector docs for more details.

await expect(page).not.toHaveSelector("#foobar")

toHaveSelectorCount

This function checks if the count of a given selector is the same as the provided value.

await expect(page).toHaveSelectorCount(".my-element", 3)

toMatchAttribute

This function checks if an element's attribute matches the provided string or regex pattern.

You can do this via a selector on the whole page:

await expect(page).toMatchAttribute("#foo", "href", "https://playwright.dev")
await expect(page).toMatchAttribute("#foo", "href", /playwright/)

Or by passing a Playwright ElementHandle:

const element = await page.$("#foo")
await expect(element).toMatchAttribute("href", "https://playwright.dev")
await expect(element).toMatchAttribute("href", /playwright/)

toMatchComputedStyle

This function checks if an element's computed style property matches the provided string or regex pattern.

You can do this via a selector on the whole page:

await expect(page).toMatchComputedStyle("#my-element", "color", "rgb(0, 0, 0)")
await expect(page).toMatchComputedStyle("#my-element", "color", /rgb/)

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toMatchComputedStyle("color", "rgb(0, 0, 0)")
await expect(element).toMatchComputedStyle("color", /rgb/)

toMatchText

This function checks if the textContent of a given element matches the provided string or regex pattern.

You can do this via a selector on the whole page:

await expect(page).toMatchText("#my-element", "Playwright")
await expect(page).toMatchText("#my-element", /Play.+/)

Or without a selector which will use the body element:

await expect(page).toMatchText("Playwright")
await expect(page).toMatchText(/Play.+/)

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toMatchText("Playwright")
await expect(element).toMatchText(/Play.+/)

toMatchTitle

This function checks if the page or frame title matches the provided string or regex pattern.

await expect(page).toMatchTitle("My app - page 1")
await expect(page).toMatchTitle(/My app - page \d/)

toMatchURL

This function checks if the current page's URL matches the provided string or regex pattern.

await expect(page).toMatchURL("https://github.com")
await expect(page).toMatchURL(/github\.com/)

toMatchValue

This function checks if the value of a given element is the same as the provided string or regex pattern.

You can do this via a selector or the element directly:

await expect(page).toMatchValue("#my-element", "Playwright")
await expect(page).toMatchValue("#my-element", /Play.+/)

Or by passing a Playwright ElementHandle:

const element = await page.$("#my-element")
await expect(element).toMatchValue("Playwright")
await expect(element).toMatchValue(/Play.+/)

Examples

import playwright from "playwright-chromium"

describe("GitHub Playwright project", () => {
  it("should should have Playwright in the README heading", async () => {
    const browser = await playwright.chromium.launch()
    const page = await browser.newPage()
    await page.goto("https://github.com/microsoft/playwright")
    await expect(page).toMatchText("#readme h1", "Playwright")
    // or also all of them via the not property
    await expect(page).not.toMatchText("this-is-no-anywhere", {
      timeout: 1 * 1000,
    })
    await browser.close()
  })
})

TypeScript

There are typings available. For that just import

import "expect-playwright"

at the top of your test file or include it globally in your tsconfig.json.

Inspired by

⚠️ We recommend the official Playwright test runner ⚠️

Author: Playwright-community
Source Code: https://github.com/playwright-community/expect-playwright 
License: MIT license

#node #testing #playwright #jest 

Expect-playwright: Expect Utility Matcher Functions

Playwright-fluent: Fluent API Around Playwright

playwright-fluent

Fluent API around Playwright

Installation

npm i --save playwright-fluent

If not already installed, the playwright package should also be installed with a version >= 1.12.0

Usage

import { PlaywrightFluent, userDownloadsDirectory } from 'playwright-fluent';

const p = new PlaywrightFluent();

await p
  .withBrowser('chromium')
  .withOptions({ headless: false })
  .withCursor()
  .withDialogs()
  .recordPageErrors()
  .recordFailedRequests()
  .recordDownloadsTo(userDownloadsDirectory)
  .emulateDevice('iPhone 6 landscape')
  .navigateTo('https://reactstrap.github.io/components/form/')
  .click('#exampleEmail')
  .typeText('foo.bar@baz.com')
  .pressKey('Tab')
  .expectThatSelector('#examplePassword')
  .hasFocus()
  .typeText("don't tell!")
  .pressKey('Tab')
  .expectThatSelector('#examplePassword')
  .hasClass('is-valid')
  .hover('#exampleCustomSelect')
  .select('Value 3')
  .in('#exampleCustomSelect')
  .close();

This package provides also a Selector API that enables to find and target a DOM element or a collection of DOM elements embedded in complex DOM Hierarchy:

const selector = p
  .selector('[role="row"]') // will get all dom elements, within the current page, with the attribute role="row"
  .withText('foobar') // will filter only those that contain the text 'foobar'
  .find('td') // from previous result(s), find all embedded <td> elements
  .nth(2); // take only the second cell

await p.expectThat(selector).hasText('foobar-2');

Usage with Iframes

This fluent API enables to seamlessly navigate inside an iframe and switch back to the page:

const p = new PlaywrightFluent();
const selector = 'iframe';
const inputInIframe = '#input-inside-iframe';
const inputInMainPage = '#input-in-main-page';
await p
  .withBrowser('chromium')
  .withOptions({ headless: false })
  .withCursor()
  .navigateTo(url)
  .hover(selector)
  .switchToIframe(selector)
  .click(inputInIframe)
  .typeText('hey I am in the iframe')
  .switchBackToPage()
  .click(inputInMainPage)
  .typeText('hey I am back in the page!');

Usage with Dialogs

This fluent API enables to handle alert, prompt and confirm dialogs:

const p = new PlaywrightFluent();

await p
  .withBrowser(browser)
  .withOptions({ headless: true })
  .WithDialogs()
  .navigateTo(url)
  // do some stuff that will open a dialog
  .waitForDialog()
  .expectThatDialog()
  .isOfType('prompt')
  .expectThatDialog()
  .hasMessage('Please say yes or no')
  .expectThatDialog()
  .hasValue('yes')
  .typeTextInDialogAndSubmit('foobar');

Usage with the tracing API

This fluent API enables to handle the playwright tracing API in the following way:

const p = new PlaywrightFluent();

await p
  .withBrowser(browser)
  .withOptions({ headless: true })
  .withTracing()
  .withCursor()
  .startTracing({ title: 'my first trace' })
  .navigateTo(url)
  // do some stuff on the opened page
  .stopTracingAndSaveTrace({ path: path.join(__dirname, 'trace1.zip') })
  // do other stuff
  .startTracing({ title: 'my second trace' })
  // do other stuff
  .stopTracingAndSaveTrace({ path: path.join(__dirname, 'trace2.zip') });

Usage with collection of elements

This fluent API enables to perform actions and assertions on a collection of DOM elements with a forEach() operator.

See it below in action on ag-grid where all athletes with Julia in their name must be selected:

demo-for-each

const p = new PlaywrightFluent();

const url = `https://www.ag-grid.com/javascript-data-grid/keyboard-navigation/`;
const cookiesConsentButton = p
  .selector('#onetrust-button-group')
  .find('button')
  .withText('Accept All Cookies');

const gridContainer = 'div#myGrid';
const rowsContainer = 'div.ag-body-viewport div.ag-center-cols-container';
const rows = p.selector(gridContainer).find(rowsContainer).find('div[role="row"]');
const filter = p.selector(gridContainer).find('input[aria-label="Athlete Filter Input"]').parent();

await p
  .withBrowser('chromium')
  .withOptions({ headless: false })
  .withCursor()
  .navigateTo(url)
  .click(cookiesConsentButton)
  .switchToIframe('iframe[title="grid-keyboard-navigation"]')
  .hover(gridContainer)
  .click(filter)
  .typeText('Julia')
  .pressKey('Enter')
  .expectThat(rows.nth(1))
  .hasText('Julia');

await rows.forEach(async (row) => {
  const checkbox = row
    .find('input')
    .withAriaLabel('Press Space to toggle row selection (unchecked)')
    .parent();
  await p.click(checkbox);
});

Usage with Stories

This package provides a way to write tests as functional components called Story:

stories.ts

import { Story, StoryWithProps } from 'playwright-fluent';

export interface StartAppProps {
  browser: BrowserName;
  isHeadless: boolean;
  url: string;
}

// first story: start the App
export const startApp: StoryWithProps<StartAppProps> = async (p, props) => {
  await p
    .withBrowser(props.browser)
    .withOptions({ headless: props.isHeadless })
    .withCursor()
    .navigateTo(props.url);
}

// second story: fill in the form
export const fillForm: Story = async (p) => {
  await p
    .click(selector)
    .select(option)
    .in(customSelect)
    ...;
};

// threrd story: submit form
export const submitForm: Story = async (p) => {
  await p
    .click(selector);
};

// fourth story: assert
export const elementIsVisible: Story = async (p) => {
  await p
    .expectThatSelector(selector)
    .isVisible();
};

test.ts

import { startApp, fillForm } from 'stories';
import { PlaywrightFluent } from 'playwright-fluent';
const p = new PlaywrightFluent();

await p
  .runStory(startApp, { browser: 'chrome', isHeadless: false, url: 'http://example.com' })
  .runStory(fillForm)
  .close();

// Also methods synonyms are available to achieve better readability
const user = new PlaywrightFluent();
await user
  .do(startApp, { browser: 'chrome', isHeadless: false, url: 'http://example.com' })
  .and(fillForm)
  .attemptsTo(submitForm)
  .verifyIf(elementIsVisible)
  .close();

Usage with mocks

This fluent API provides a generic and simple infrastructure for massive request interception and response mocking.

This Mock API leverages the Playwright request interception infrastructure and will enable you to mock all HTTP requests in order to test the front in complete isolation from the backend.

Read more about the Fluent Mock API

This API is still a draft and is in early development, but stay tuned!

Contributing

Check out our contributing guide.

Resources

FAQ

Q: How does playwright-fluent relate to Playwright?

playwright-fluent is just a wrapper around the Playwright API. It leverages the power of Playwright by giving a Fluent API, that enables to consume the Playwright API with chainable actions and assertions. The purpose of playwright-fluent is to be able to write e2e tests in a way that makes tests more readable, reusable and maintainable.

Q: Can I start using playwright-fluent in my existing code base?

Yes you can.

import { PlaywrightFluent } from 'playwright-fluent';

// just create a new instance with playwright's browser and page instances
const p = new PlaywrightFluent(browser, page);

// you can also create a new instance with playwright's browser and frame instances
const p = new PlaywrightFluent(browser, frame);

// now you can use the fluent API

Q: Can I use Playwright together with the playwright-fluent?

Yes you can. To use the Playwright API, call the currentBrowser() and/or currentPage() methods exposed by the fluent API:

const browser = 'chromium';
const p = new PlaywrightFluent();
await p
  .withBrowser(browser)
  .emulateDevice('iPhone 6 landscape')
  .withCursor()
  .navigateTo('https://reactstrap.github.io/components/form/')
  ...;

// now if you want to use the playwright API from this point:
const browser = p.currentBrowser();
const page = p.currentPage();

// the browser and page objects are standard playwright objects
// so now you are ready to go by using the playwright API

Q: What can I do with the currently published npm package playwright-fluent?

The documentations:

reflect the current status of the development and are inline with the published package.

Q: Do you have some samples on how to use this library?

Yes, have a look to this demo project with jest, this demo project with cucumber-js v6 or this demo project with cucumber-js v7.

Fluent API | Selector API | Assertion API | Mock API | FAQ | with jest | with cucumber-js v6 | with cucumber-js v7

Author: Hdorgeval
Source Code: https://github.com/hdorgeval/playwright-fluent 
License: MIT license

#node #playwright #testing #api 

Playwright-fluent: Fluent API Around Playwright

Playwright-perl: Perl Bindings for Playwright

playwright-perl 

Perl bindings for playwright, the amazing cross browser testing framework from Microsoft

Has this ever happened to you?

You're writing some acceptance test with Selenium::Remote:Driver, but you figure out selenium is a dead protocol? Finally, a solution!

Here's how it works

A little node webserver written in express is spun up which exposes the entire playwright API. We ensure the node deps are installed in a BEGIN block, and then spin up the proxy server. You then use playwright more or less as normal; see the POD in Playwright.pm for more details.

See example.pl for usage examples.

Supported Perls

Everything newer than 5.28 is supported.

Things should work on 5.20 or newer, but... Tests might fail due to Temp file weirdness with Test::MockFile.

Supported OS

Everything seems to work fine on OSX and Linux.

On Windows, you will have to approve a UAC prompt to exempt playwright_server from being firewalled off.

How2develop

Everything should more or less set itself up automatically, or explode and tell you what to do. I assume you know how to get cpanm.

You might want to use distro packages for some of these:

sudo cpanm Dist::Zilla
dzil authordeps --missing | sudo cpanm
dzil listdeps --missing | sudo cpanm

From there you'll need nvm to get the latest verison of node working:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.bashrc
nvm install
nvm use

Running dzil test should let you know if your kit is good to develop.

Actually running stuff will look like this after you generate the API json and modules:

PATH="$(pwd)/bin:$PATH" perl -Ilib example.pl

Dealing with api.json and generating modules

Playwright doesn't ship their api.json with the distribution on NPM. You have to generate it from their repo.

clone it in a directory that is the same as the one containing this repository. then run generate_api_json.sh to get things working such that the build scripts know what to do.

Then run generate_perl_modules.pl to get the accessor classes built based off of the spec, and insert the spec JSON into the playwright_server binary.

To make life simple, you can just run run_example in the TLD when debugging.

Questions?

Hop into the playwright slack, and check out the #playwright-perl channel therein. I'm watching that space and should be able to answer your questions. https://aka.ms/playwright-slack

Apparently Microsoft is trying to migrate to Github's built in forums, so I've activated discussions on this project too (see the tab at the top).

Author: Teodesian
Source Code: https://github.com/teodesian/playwright-perl 
License: MIT license

#node #playwright #perl 

Playwright-perl: Perl Bindings for Playwright
Oral  Brekke

Oral Brekke

1656083520

Playwright-rust: Playwright Port to Rust

🎭 Playwright for Rust 

Playwright is a rust library to automate Chromium, Firefox and WebKit built on top of Node.js library.

Installation

[dependencies]
playwright = "0.0.18"

Usage

use playwright::Playwright;

#[tokio::main]
async fn main() -> Result<(), playwright::Error> {
    let playwright = Playwright::initialize().await?;
    playwright.prepare()?; // Install browsers
    let chromium = playwright.chromium();
    let browser = chromium.launcher().headless(true).launch().await?;
    let context = browser.context_builder().build().await?;
    let page = context.new_page().await?;
    page.goto_builder("https://example.com/").goto().await?;

    // Exec in browser and Deserialize with serde
    let s: String = page.eval("() => location.href").await?;
    assert_eq!(s, "https://example.com/");
    page.click_builder("a").click().await?;
    Ok(())
}

Async runtimes

These runtimes have passed tests. You can disable tokio, the default feature, and then choose another.

Incompatibility

Functions do not have default arguments in rust. Functions with two or more optional arguments are now passed with the builder pattern.

Playwright Driver

Playwright is designed as a server-client. All playwright client dependent on the driver: zip of core js library and Node.js. Application uses this library will be bundled the driver into rust binary at build time. There is an overhead of unzipping on the first run.

NOTICE

playwright-rust redistributes Playwright licensed under the Apache 2.0.
Playwright has NOTICE:
"""
Playwright
Copyright (c) Microsoft Corporation

This software contains code derived from the Puppeteer project (https://github.com/puppeteer/puppeteer),
available under the Apache 2.0 license (https://github.com/puppeteer/puppeteer/blob/master/LICENSE).
"""

Browser automation in rust

Other languages

Author: Octaltree
Source Code: https://github.com/octaltree/playwright-rust 
License: 

#node #playwright #rust 

Playwright-rust: Playwright Port to Rust
Oral  Brekke

Oral Brekke

1656076140

Crystal Version Of The Playwright Testing & Automation Library

🎭 Playwright for Crystal 

Playwright-cr is a Crystal library to automate 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. See how Playwright is better.

 LinuxmacOSWindows
Chromium 89.0.4344.0βœ…βœ…βœ…
WebKit 14.1βœ…βœ…βœ…
Firefox 85.0b1βœ…βœ…βœ…

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

Playwright Dependencies

Playwright Crystal relies on two external components: The Playwright driver and the browsers.

Playwright Driver

Playwright drivers will be downloaded to the bin/driver folder, and browsers will be installed at shard installation time.

Installation

Add the dependency to your shard.yml:

dependencies:
  playwright:
    github: naqvis/playwright-cr

Run shards install

Usage

Page Screenshot

This code snippet navigates to whatsmyuseragent.org in Chromium, Firefox and WebKit, and saves 3 screenshots.

require "playwright"

playwright = Playwright.create
browser_types = [playwright.chromium,
                 playwright.webkit,
                 playwright.firefox]

browser_types.each do |browser_type|
  browser = browser_type.launch
  context = browser.new_context(Playwright::Browser::NewContextOptions.new(
    viewport: Playwright::Page::ViewPort.new(800, 600)))
  page = context.new_page
  page.goto("http://whatsmyuseragent.org/")
  page.screenshot(Playwright::Page::ScreenshotOptions.new(path: Path["screenshot-#{browser_type.name}.png"]))
  browser.close
end
playwright.close

Mobile and geolocation

This snippet emulates Mobile Chromium on a device at a given geolocation, navigates to openstreetmap.org, performs action and takes a screenshot.

require "playwright"

playwright = Playwright.create
browser = playwright.chromium.launch(Playwright::BrowserType::LaunchOptions.new(headless: false))
pixel2 = playwright.devices["Pixel 2"]
context = browser.new_context(Playwright::Browser::NewContextOptions.new(
  viewport: Playwright::Page::ViewPort.new(pixel2.viewport.width, pixel2.viewport.height),
  user_agent: pixel2.user_agent,
  device_scale_factor: pixel2.device_scale_factor.to_i,
  is_mobile: pixel2.is_mobile,
  has_touch: pixel2.has_touch,
  locale: "en-US",
  geolocation: Playwright::Geolocation.new(41.889938, 12.492507),
  permissions: ["geolocation"]))
page = context.new_page
page.goto("https://www.openstreetmap.org/")
page.click("a[data-original-title=\"Show My Location\"]")
page.screenshot(Playwright::Page::ScreenshotOptions.new(path: Path["colosseum-pixel2.png"]))
browser.close
playwright.close

Evaluate in browser context

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

require "playwright"

playwright = Playwright.create
browser = playwright.firefox.launch(Playwright::BrowserType::LaunchOptions.new(headless: false))
context = browser.new_context
page = context.new_page
page.goto("https://www.example.com/")
dimensions = page.evaluate(%(
  () => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    }
  }
))
puts dimensions # => {"width" => 1280, "height" => 720, "deviceScaleFactor" => 1}
browser.close
playwright.close

Intercept network requests

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

require "playwright"

playwright = Playwright.create
browser = playwright.webkit.launch
context = browser.new_context
page = context.new_page
page.route("**", Playwright::Consumer(Playwright::Route).new { |route|
  puts route.request.url
  route.continue
})
page.goto("http://todomvc.com")
browser.close
playwright.close

Refer to spec for more samples and usages. This shard comes with 350+ test cases :)

Development

To run all tests:

crystal spec

By Default browser is chromium, but you can change the browser via setting environment variable of BROWSER=firefox or BROWSER=webkit for specs to run using different browser. By default tests are run in headless mode. But if you would like the tests to run in headful way, set the environment variable HEADFUL=true.

Contributing

  1. Fork it (https://github.com/naqvis/playwright-cr/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

Website | API Reference

Author: Naqvis
Source Code: https://github.com/naqvis/playwright-cr 
License: MIT license

#node #playwright #testing 

Crystal Version Of The Playwright Testing & Automation Library
Oral  Brekke

Oral Brekke

1656068700

Playwright Client for Ruby

🎭 Playwright client for Ruby

Getting Started

gem 'playwright-ruby-client'

and then 'bundle install'.

Since playwright-ruby-client doesn't include the playwright driver, we have to install playwright in advance.

npm install playwright
./node_modules/.bin/playwright install

And set playwright_cli_executable_path: './node_modules/.bin/playwright'

Prefer playwrighting without Node.js?

Instead of npm, you can also directly download playwright driver from playwright.azureedge.net/builds/. The URL can be easily detected from here

Capture a site

require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
  playwright.chromium.launch(headless: false) do |browser|
    page = browser.new_page
    page.goto('https://github.com/YusukeIwaki')
    page.screenshot(path: './YusukeIwaki.png')
  end
end

image

Simple scraping

require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
  playwright.chromium.launch(headless: false) do |browser|
    page = browser.new_page
    page.goto('https://github.com/')

    form = page.query_selector("form.js-site-search-form")
    search_input = form.query_selector("input.header-search-input")
    search_input.click
    page.keyboard.type("playwright")
    page.expect_navigation {
      page.keyboard.press("Enter")
    }

    list = page.query_selector("ul.repo-list")
    items = list.query_selector_all("div.f4")
    items.each do |item|
      title = item.eval_on_selector("a", "a => a.innerText")
      puts("==> #{title}")
    end
  end
end
$ bundle exec ruby main.rb
==> microsoft/playwright
==> microsoft/playwright-python
==> microsoft/playwright-cli
==> checkly/headless-recorder
==> microsoft/playwright-sharp
==> playwright-community/jest-playwright
==> microsoft/playwright-test
==> mxschmitt/playwright-go
==> microsoft/playwright-java
==> MarketSquare/robotframework-browser

Android browser automation

require 'playwright'

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
  devices = playwright.android.devices
  unless devices.empty?
    device = devices.last
    begin
      puts "Model: #{device.model}"
      puts "Serial: #{device.serial}"
      puts device.shell('ls /system')

      device.launch_browser do |context|
        page = context.pages.first
        page.goto('https://github.com/YusukeIwaki')
        page.click('header button')
        page.click('input[name="q"]')
        page.keyboard.type('puppeteer')
        page.expect_navigation {
          page.keyboard.press('Enter')
        }
        page.screenshot(path: 'YusukeIwaki.android.png')
      end
    ensure
      device.close
    end
  end
end

android-browser

Android native automation

We have to download android-driver for Playwright in advance.

wget https://github.com/microsoft/playwright/raw/master/bin/android-driver-target.apk -O /path/to/playwright-driver/package/bin/android-driver-target.apk
wget https://github.com/microsoft/playwright/raw/master/bin/android-driver.apk -O /path/to/playwright-driver/package/bin/android-driver.apk

(If you downloaded Playwright via npm, replace /path/to/playwright-driver/package/ with ./node_modules/playwright/ above.)

require 'playwright'

Playwright.create(playwright_cli_executable_path: ENV['PLAYWRIGHT_CLI_EXECUTABLE_PATH']) do |playwright|
  devices = playwright.android.devices
  unless devices.empty?
    device = devices.last
    begin
      device.shell('input keyevent POWER')
      device.shell('input keyevent POWER')
      device.shell('input keyevent 82')
      sleep 1
      device.shell('cmd statusbar expand-notifications')

      # pp device.tree
      # pp device.info(res: 'com.android.systemui:id/clock')
      device.tap_on(res: 'com.android.systemui:id/clock')
    ensure
      device.close
    end
  end
end

Communicate with Playwright server

If your environment doesn't accept installing browser or creating browser process, consider separating Ruby client and Playwright server.

structure

For launching Playwright server, just execute:

npx playwright install && npx playwright run-server --port 8080

and we can connect to the server with the code like this:

Playwright.connect_to_playwright_server('ws://127.0.0.1:8080') do |playwright|
  playwright.chromium.launch do |browser|
    page = browser.new_page
    page.goto('https://github.com/YusukeIwaki')
    page.screenshot(path: './YusukeIwaki.png')
  end
end

When Playwright.connect_to_playwright_server is used, playwright_cli_executable_path is not required.

For more detailed instraction, refer this article: https://playwright-ruby-client.vercel.app/docs/article/guides/playwright_on_alpine_linux

Code of Conduct

Everyone interacting in the Playwright project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Docs | API

Author: YusukeIwaki
Source Code: https://github.com/YusukeIwaki/playwright-ruby-client 
License: MIT license

#node #playwright #ruby #client 

Playwright Client for Ruby
Oral  Brekke

Oral Brekke

1656061260

Playwright-go: Playwright Port for Golang

🎭 Playwright for Go

Playwright is a Go library to automate 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.

 LinuxmacOSWindows
Chromium 101.0.4929.0βœ…βœ…βœ…
WebKit 15.4βœ…βœ…βœ…
Firefox 97.0.1βœ…βœ…βœ…

Headless execution is supported for all the browsers on all platforms.

Installation

go get github.com/playwright-community/playwright-go

Install the browsers and OS dependencies:

go run github.com/playwright-community/playwright-go/cmd/playwright install --with-deps
# Or
go install github.com/playwright-community/playwright-go/cmd/playwright
playwright install --with-deps

Alternatively you can do it inside your program via which downloads the driver and browsers:

err := playwright.Install()

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

Example

The following example crawls the current top voted items from Hacker News.

package main

import (
    "fmt"
    "log"

    "github.com/playwright-community/playwright-go"
)

func main() {
    pw, err := playwright.Run()
    if err != nil {
        log.Fatalf("could not start playwright: %v", err)
    }
    browser, err := pw.Chromium.Launch()
    if err != nil {
        log.Fatalf("could not launch browser: %v", err)
    }
    page, err := browser.NewPage()
    if err != nil {
        log.Fatalf("could not create page: %v", err)
    }
    if _, err = page.Goto("https://news.ycombinator.com"); err != nil {
        log.Fatalf("could not goto: %v", err)
    }
    entries, err := page.QuerySelectorAll(".athing")
    if err != nil {
        log.Fatalf("could not get entries: %v", err)
    }
    for i, entry := range entries {
        titleElement, err := entry.QuerySelector("td.title > a")
        if err != nil {
            log.Fatalf("could not get title element: %v", err)
        }
        title, err := titleElement.TextContent()
        if err != nil {
            log.Fatalf("could not get text content: %v", err)
        }
        fmt.Printf("%d: %s\n", i+1, title)
    }
    if err = browser.Close(); err != nil {
        log.Fatalf("could not close browser: %v", err)
    }
    if err = pw.Stop(); err != nil {
        log.Fatalf("could not stop Playwright: %v", err)
    }
}

More examples

How does it work?

Playwright is a Node.js library which uses:

  • Chrome DevTools Protocol to communicate with Chromium
  • Patched Firefox to communicate with Firefox
  • Patched WebKit to communicate with WebKit

These patches are based on the original sources of the browsers and don't modify the browser behaviour so the browsers are basically the same (see here) as you see them in the wild. The support for different programming languages is based on exposing a RPC server in the Node.js land which can be used to allow other languages to use Playwright without implementing all the custom logic:

The bridge between Node.js and the other languages is basically a Node.js runtime combined with Playwright which gets shipped for each of these languages (around 50MB) and then communicates over stdio to send the relevant commands. This will also download the pre-compiled browsers.

Is Playwright for Go ready?

We are ready for your feedback, but we are still covering Playwright Go with the tests.

Resources

Looking for maintainers and see here. Thanks!       

API reference | Example recipes

Author: Playwright-community
Source Code: https://github.com/playwright-community/playwright-go 
License: MIT license

#node #playwright #go #golang 

Playwright-go: Playwright Port for Golang
Oral  Brekke

Oral Brekke

1656057480

Java Version Of The Playwright Testing and Automation Library

🎭 Playwright for Java

Playwright is a Java library to automate 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
macOSWindows
Chromium 102.0.5005.40βœ…βœ…
WebKit 15.4βœ…βœ…
Firefox 99.0.1βœ…βœ…

Usage

Playwright requires Java 8 or newer.

Add Maven dependency

Playwright is distributed as a set of Maven modules. The easiest way to use it is to add one dependency to your Maven pom.xml file as described below. If you're not familiar with Maven please refer to its documentation.

To run Playwright simply add following dependency to your Maven project:

<dependency>  <groupId>com.microsoft.playwright</groupId>  <artifactId>playwright</artifactId>  <version>1.17.0</version></dependency>

Is Playwright thread-safe?

No, Playwright is not thread safe, i.e. all its methods as well as methods on all objects created by it (such as BrowserContext, Browser, Page etc.) are expected to be called on the same thread where Playwright object was created or proper synchronization should be implemented to ensure only one thread calls Playwright methods at any given time. Having said that it's okay to create multiple Playwright instances each on its own thread.

Examples

You can find Maven project with the examples here.

Page screenshot

This code snippet navigates to whatsmyuseragent.org in Chromium, Firefox and WebKit, and saves 3 screenshots.

import com.microsoft.playwright.*;import java.nio.file.Paths;import java.util.Arrays;import java.util.List;public class PageScreenshot {  public static void main(String[] args) {    try (Playwright playwright = Playwright.create()) {      List<BrowserType> browserTypes = Arrays.asList(        playwright.chromium(),        playwright.webkit(),        playwright.firefox()      );      for (BrowserType browserType : browserTypes) {        try (Browser browser = browserType.launch()) {          BrowserContext context = browser.newContext();          Page page = context.newPage();          page.navigate("http://whatsmyuseragent.org/");          page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("screenshot-" + browserType.name() + ".png")));        }      }    }  }}

Mobile and geolocation

This snippet emulates Mobile Chromium on a device at a given geolocation, navigates to openstreetmap.org, performs action and takes a screenshot.

import com.microsoft.playwright.options.*;import com.microsoft.playwright.*;import java.nio.file.Paths;import static java.util.Arrays.asList;public class MobileAndGeolocation {  public static void main(String[] args) {    try (Playwright playwright = Playwright.create()) {      Browser browser = playwright.chromium().launch();      BrowserContext context = browser.newContext(new Browser.NewContextOptions()        .setUserAgent("Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36")        .setViewportSize(411, 731)        .setDeviceScaleFactor(2.625)        .setIsMobile(true)        .setHasTouch(true)        .setLocale("en-US")        .setGeolocation(41.889938, 12.492507)        .setPermissions(asList("geolocation")));      Page page = context.newPage();      page.navigate("https://www.openstreetmap.org/");      page.click("a[data-original-title=\"Show My Location\"]");      page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("colosseum-pixel2.png")));    }  }}

Evaluate JavaScript in browser

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

import com.microsoft.playwright.*;public class EvaluateInBrowserContext {  public static void main(String[] args) {    try (Playwright playwright = Playwright.create()) {      Browser browser = playwright.firefox().launch();      BrowserContext context = browser.newContext();      Page page = context.newPage();      page.navigate("https://www.example.com/");      Object dimensions = page.evaluate("() => {\n" +        "  return {\n" +        "      width: document.documentElement.clientWidth,\n" +        "      height: document.documentElement.clientHeight,\n" +        "      deviceScaleFactor: window.devicePixelRatio\n" +        "  }\n" +        "}");      System.out.println(dimensions);    }  }}

Intercept network requests

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

import com.microsoft.playwright.*;public class InterceptNetworkRequests {  public static void main(String[] args) {    try (Playwright playwright = Playwright.create()) {      Browser browser = playwright.webkit().launch();      BrowserContext context = browser.newContext();      Page page = context.newPage();      page.route("**", route -> {        System.out.println(route.request().url());        route.resume();      });      page.navigate("http://todomvc.com");    }  }}

Documentation

Check out our official documentation site.

You can also browse javadoc online.

Contributing

Follow the instructions to build the project from source and install the driver.

Is Playwright for Java ready?

Yes, Playwright for Java is ready. v1.10.0 is the first stable release. Going forward we will adhere to semantic versioning of the API.

Website | API reference

Author: Microsoft
Source Code: https://github.com/microsoft/playwright-java 
License: Apache-2.0 license

#node #playwright #java #testing 

Java Version Of The Playwright Testing and Automation Library
Oral  Brekke

Oral Brekke

1656050040

.NET Version Of The Playwright Testing and Automation Library

Playwright for .NET 🎭 

Playwright for .NET is the official language port of Playwright, the library to automate 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.

 LinuxmacOSWindows
Chromium 103.0.5060.24βœ…βœ…βœ…
WebKit 15.4βœ…βœ…βœ…
Firefox 99.0.1βœ…βœ…βœ…

API Reference

https://playwright.dev/dotnet/docs/api/class-playwright

using System.Threading.Tasks;
using Microsoft.Playwright;

class Program
{
    public static async Task Main()
    {
        using var playwright = await Playwright.CreateAsync();
        await using var browser = await playwright.Chromium.LaunchAsync(new() { Headless = false });
        var page = await browser.NewPageAsync();
        await page.GotoAsync("https://playwright.dev/dotnet");
        await page.ScreenshotAsync(new() { Path = "screenshot.png" });
    }
}

Other languages

More comfortable in another programming language? Playwright is also available in

Documentation

https://playwright.dev/dotnet/docs/intro

Author: Microsoft
Source Code: https://github.com/microsoft/playwright-dotnet 
License: MIT license

#node #playwright #dotnet 

.NET Version Of The Playwright Testing and Automation Library
Oral  Brekke

Oral Brekke

1656042600

Python Version Of The Playwright Testing & Automation Library

🎭 Playwright for Python  

Playwright is a Python library to automate Chromium, Firefox and WebKit browsers with a single API. Playwright delivers automation that is ever-green, capable, reliable and fast. See how Playwright is better.

 LinuxmacOSWindows
Chromium 102.0.5005.61βœ…βœ…βœ…
WebKit 15.4βœ…βœ…βœ…
Firefox 99.0.1βœ…βœ…βœ…

Example

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch()
        page = browser.new_page()
        page.goto('http://whatsmyuseragent.org/')
        page.screenshot(path=f'example-{browser_type.name}.png')
        browser.close()
import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        for browser_type in [p.chromium, p.firefox, p.webkit]:
            browser = await browser_type.launch()
            page = await browser.new_page()
            await page.goto('http://whatsmyuseragent.org/')
            await page.screenshot(path=f'example-{browser_type.name}.png')
            await browser.close()

asyncio.run(main())

Other languages

More comfortable in another programming language? Playwright is also available in

Documentation

https://playwright.dev/python/docs/intro

API Reference

https://playwright.dev/python/docs/api/class-playwright

Author: Microsoft
Source Code: https://github.com/microsoft/playwright-python 
License: Apache-2.0 license

#node #playwright #python 

Python Version Of The Playwright Testing & Automation Library