chore: prepare non-api docs for non-js variants (#4969)

This commit is contained in:
Pavel Feldman 2021-01-11 09:34:49 -08:00 committed by GitHub
parent 4dbbb47583
commit 7a8214cd95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 439 additions and 147 deletions

View file

@ -124,13 +124,13 @@ Performs action and waits for given `event` to fire. If predicate is provided, i
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the page is closed before the `event` is fired.
```python-async
```python async
async with page.expect_event(event_name) as event_info:
await page.click("button")
value = await event_info.value
```
```python-sync
```python sync
with page.expect_event(event_name) as event_info:
page.click("button")
value = event_info.value
@ -148,13 +148,13 @@ Performs action and waits for given `event` to fire. If predicate is provided, i
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if browser context is closed before the `event` is fired.
```python-async
```python async
async with context.expect_event(event_name) as event_info:
await context.click("button")
value = await event_info.value
```
```python-sync
```python sync
with context.expect_event(event_name) as event_info:
context.click("button")
value = event_info.value
@ -172,13 +172,13 @@ Performs action and waits for given `event` to fire. If predicate is provided, i
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the socket is closed before the `event` is fired.
```python-async
```python async
async with ws.expect_event(event_name) as event_info:
await ws.click("button")
value = await event_info.value
```
```python-sync
```python sync
with ws.expect_event(event_name) as event_info:
ws.click("button")
value = event_info.value
@ -195,13 +195,13 @@ value = event_info.value
Performs action and waits for the required load state. It resolves when the page reaches a required load state, `load` by default. The navigation must have been committed when this method is called. If current document has
already reached the required state, resolves immediately.
```python-async
```python async
async with page.expect_load_state():
await page.click('button') # Click triggers navigation.
# Context manager waits for 'load' event.
```
```python-sync
```python sync
with page.expect_load_state():
page.click('button') # Click triggers navigation.
# Context manager waits for 'load' event.
@ -219,13 +219,13 @@ Shortcut for main frame's [`method: Frame.expectLoadState`].
Performs action and waits for the required load state. It resolves when the page reaches a required load state, `load` by default. The navigation must have been committed when this method is called. If current document has
already reached the required state, resolves immediately.
```python-async
```python async
async with frame.expect_load_state():
await frame.click('button') # Click triggers navigation.
# Context manager waits for 'load' event.
```
```python-sync
```python sync
with frame.expect_load_state():
frame.click('button') # Click triggers navigation.
# Context manager waits for 'load' event.
@ -238,7 +238,7 @@ with frame.expect_load_state():
* langs: python
- returns: <[EventContextManager]>
Performs action and wait for the next navigation. In case of multiple redirects, the navigation will resolve with
Performs action and waits for the next navigation. In case of multiple redirects, the navigation will resolve with
the response of the last redirect. In case of navigation to a different anchor or navigation due to History API
usage, the navigation will resolve with `null`.
@ -246,13 +246,13 @@ This resolves when the page navigates to a new URL or reloads. It is useful for
indirectly cause the page to navigate. e.g. The click target has an `onclick` handler that triggers navigation
from a `setTimeout`. Consider this example:
```python-async
```python async
async with page.expect_navigation():
await page.click("a.delayed-navigation") # Clicking the link will indirectly cause a navigation
# Context manager waited for the navigation to happen.
```
```python-sync
```python sync
with page.expect_navigation():
page.click("a.delayed-navigation") # Clicking the link will indirectly cause a navigation
# Context manager waited for the navigation to happen.
@ -271,7 +271,7 @@ Shortcut for main frame's [`method: Frame.expectNavigation`].
* langs: python
- returns: <[EventContextManager]>
Performs action and wait for the next navigation. In case of multiple redirects, the navigation will resolve with
Performs action and waits for the next navigation. In case of multiple redirects, the navigation will resolve with
the response of the last redirect. In case of navigation to a different anchor or navigation due to History API
usage, the navigation will resolve with `null`.
@ -279,13 +279,13 @@ This resolves when the page navigates to a new URL or reloads. It is useful for
indirectly cause the page to navigate. e.g. The click target has an `onclick` handler that triggers navigation
from a `setTimeout`. Consider this example:
```python-async
```python async
async with frame.expect_navigation():
await frame.click("a.delayed-navigation") # Clicking the link will indirectly cause a navigation
# Context manager waited for the navigation to happen.
```
```python-sync
```python sync
with frame.expect_navigation():
frame.click("a.delayed-navigation") # Clicking the link will indirectly cause a navigation
# Context manager waited for the navigation to happen.

View file

@ -35,7 +35,7 @@ const checked = await page.getAttribute('input', 'checked');
assert(checked);
```
```python-async
```python async
# Assert text content
content = await page.text_content('nav:first-child')
assert content == 'home'
@ -53,7 +53,7 @@ checked = await page.get_attribute('input', 'checked')
assert checked
```
```python-sync
```python sync
# Assert text content
content = page.text_content('nav:first-child')
assert content == 'home'
@ -106,7 +106,7 @@ const classNames = await elementHandle.getAttribute('class');
assert(classNames.includes('highlighted'));
```
```python-async
```python async
# Get the element handle
element_handle = page.wait_for_selector('#box')
@ -119,7 +119,7 @@ class_names = await element_handle.get_attribute('class')
assert 'highlighted' in class_names
```
```python-sync
```python sync
# Get the element handle
element_handle = page.wait_for_selector('#box')
@ -171,7 +171,7 @@ const length = await page.$$eval('li.selected', (items) => items.length);
assert(length === 3);
```
```python-async
```python async
# Assert local storage value
user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id
@ -190,7 +190,7 @@ length = await page.eval_on_selector_all('li.selected', '(items) => items.length
assert length == 3
```
```python-sync
```python sync
# Assert local storage value
user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id

View file

@ -36,7 +36,7 @@ await page.click('text=Submit');
// Verify app is logged in
```
```python-async
```python async
page = await context.new_page()
await page.goto('https://github.com/login')
@ -48,7 +48,7 @@ await page.click('text=Submit')
# Verify app is logged in
```
```python-sync
```python sync
page = context.new_page()
page.goto('https://github.com/login')
@ -88,7 +88,7 @@ const storageState = JSON.parse(process.env.STORAGE);
const context = await browser.newContext({ storageState });
```
```python-async
```python async
import json
import os
# Save storage state and store as an env variable
@ -100,7 +100,7 @@ storage_state = json.loads(os.environ["STORAGE"])
context = await browser.new_context(storage_state=storage_state)
```
```python-sync
```python sync
import json
import os
# Save storage state and store as an env variable
@ -134,7 +134,7 @@ await context.addInitScript(storage => {
}, sessionStorage);
```
```python-async
```python async
import os
# Get session storage and store as env variable
session_storage = await page.evaluate("() => JSON.stringify(sessionStorage)")
@ -152,7 +152,7 @@ await context.add_init_script(storage => {
}, session_storage)
```
```python-sync
```python sync
import os
# Get session storage and store as env variable
session_storage = page.evaluate("() => JSON.stringify(sessionStorage)")
@ -217,7 +217,7 @@ const context = await chromium.launchPersistentContext(userDataDir, { headless:
// Execute login steps manually in the browser window
```
```python-async
```python async
import asyncio
from playwright import async_playwright
@ -230,7 +230,7 @@ async def main():
asyncio.get_event_loop().run_until_complete(main())
```
```python-sync
```python sync
from playwright import sync_playwright
with sync_playwright() as p:

View file

@ -50,13 +50,13 @@ Suggested configuration
});
```
```python-async
```python async
browser = await playwright.chromium.launch(
args=['--disable-dev-shm-usage']
)
```
```python-sync
```python sync
browser = playwright.chromium.launch({
args=['--disable-dev-shm-usage']
})
@ -203,11 +203,11 @@ const { chromium } = require('playwright');
const browser = await chromium.launch({ chromiumSandbox: false });
```
```python-async
```python async
browser = await playwright.chromium.launch(chromiumSandbox=False)
```
```python-sync
```python sync
browser = playwright.chromium.launch(chromiumSandbox=False)
```
@ -287,7 +287,7 @@ const { chromium } = require('playwright');
const browser = await chromium.launch({ headless: false });
```
```python-async
```python async
import asyncio
from playwright import async_playwright
@ -299,7 +299,7 @@ async def main():
asyncio.get_event_loop().run_until_complete(main())
```
```python-sync
```python sync
from playwright import sync_playwright
with sync_playwright() as p:

View file

@ -29,7 +29,7 @@ const browser = await chromium.launch({ headless: false });
await browser.close();
```
```python-async
```python async
import asyncio
from playwright import async_playwright
@ -41,7 +41,7 @@ async def main():
asyncio.get_event_loop().run_until_complete(main())
```
```python-sync
```python sync
from playwright import sync_playwright
with sync_playwright() as p:
@ -69,12 +69,12 @@ const browser = await chromium.launch();
const context = await browser.newContext();
```
```python-async
```python async
browser = await playwright.chromium.launch()
context = await browser.new_context()
```
```python-sync
```python sync
browser = playwright.chromium.launch()
context = browser.new_context()
```
@ -95,7 +95,7 @@ const context = await browser.newContext({
});
```
```python-async
```python async
import asyncio
from playwright import async_playwright
@ -116,7 +116,7 @@ async def main():
asyncio.get_event_loop().run_until_complete(main())
```
```python-sync
```python sync
from playwright import sync_playwright
with sync_playwright() as p:
@ -161,7 +161,7 @@ console.log(page.url());
window.location.href = 'https://example.com';
```
```python-async
```python async
page = await context.new_page()
# Navigate explicitly, similar to entering a URL in the browser.
@ -178,7 +178,7 @@ print(page.url)
# window.location.href = 'https://example.com'
```
```python-sync
```python sync
page = context.new_page()
# Navigate explicitly, similar to entering a URL in the browser.
@ -219,7 +219,7 @@ const frame = await frameElementHandle.contentFrame();
await frame.fill('#username-input', 'John');
```
```python-async
```python async
# Get frame using the frame's name attribute
frame = page.frame('frame-login')
@ -234,7 +234,7 @@ frame = await frame_element_handle.content_frame()
await frame.fill('#username-input', 'John')
```
```python-sync
```python sync
# Get frame using the frame's name attribute
frame = page.frame('frame-login')
@ -274,12 +274,12 @@ Some examples below:
await page.click('data-test-id=foo');
```
```python-async
```python async
# Using data-test-id= selector engine
await page.click('data-test-id=foo')
```
```python-sync
```python sync
# Using data-test-id= selector engine
page.click('data-test-id=foo')
```
@ -290,13 +290,13 @@ await page.click('div');
await page.click('//html/body/div');
```
```python-async
```python async
# CSS and XPath selector engines are automatically detected
await page.click('div')
await page.click('//html/body/div')
```
```python-sync
```python sync
# CSS and XPath selector engines are automatically detected
page.click('div')
page.click('//html/body/div')
@ -307,12 +307,12 @@ page.click('//html/body/div')
await page.click('text=Hello w');
```
```python-async
```python async
# Find node by text substring
await page.click('text=Hello w')
```
```python-sync
```python sync
# Find node by text substring
page.click('text=Hello w')
```
@ -323,13 +323,13 @@ await page.click('css=div');
await page.click('xpath=//html/body/div');
```
```python-async
```python async
# Explicit CSS and XPath notation
await page.click('css=div')
await page.click('xpath=//html/body/div')
```
```python-sync
```python sync
# Explicit CSS and XPath notation
page.click('css=div')
page.click('xpath=//html/body/div')
@ -340,12 +340,12 @@ page.click('xpath=//html/body/div')
await page.click('css:light=div');
```
```python-async
```python async
# Only search light DOM, outside WebComponent shadow DOM:
await page.click('css:light=div')
```
```python-sync
```python sync
# Only search light DOM, outside WebComponent shadow DOM:
page.click('css:light=div')
```
@ -357,12 +357,12 @@ Selectors using the same or different engines can be combined using the `>>` sep
await page.click('#free-month-promo >> text=Sign Up');
```
```python-async
```python async
# Click an element with text 'Sign Up' inside of a #free-month-promo.
await page.click('#free-month-promo >> text=Sign Up')
```
```python-sync
```python sync
# Click an element with text 'Sign Up' inside of a #free-month-promo.
page.click('#free-month-promo >> text=Sign Up')
```
@ -372,12 +372,12 @@ page.click('#free-month-promo >> text=Sign Up')
const sectionText = await page.$eval('*css=section >> text=Selectors', e => e.textContent);
```
```python-async
```python async
# Capture textContent of a section that contains an element with text 'Selectors'.
section_text = await page.eval_on_selector('*css=section >> text=Selectors', 'e => e.textContent')
```
```python-sync
```python sync
# Capture textContent of a section that contains an element with text 'Selectors'.
section_text = page.eval_on_selector('*css=section >> text=Selectors', 'e => e.textContent')
```
@ -401,12 +401,12 @@ and [actionable](./actionability.md). For example, click will:
await page.fill('#search', 'query');
```
```python-async
```python async
# Playwright waits for #search element to be in the DOM
await page.fill('#search', 'query')
```
```python-sync
```python sync
# Playwright waits for #search element to be in the DOM
page.fill('#search', 'query')
```
@ -417,13 +417,13 @@ page.fill('#search', 'query')
await page.click('#search');
```
```python-async
```python async
# Playwright waits for element to stop animating
# and accept clicks.
await page.click('#search')
```
```python-sync
```python sync
# Playwright waits for element to stop animating
# and accept clicks.
page.click('#search')
@ -438,14 +438,14 @@ await page.waitForSelector('#search', { state: 'attached' });
await page.waitForSelector('#promo');
```
```python-async
```python async
# Wait for #search to appear in the DOM.
await page.wait_for_selector('#search', state='attached')
# Wait for #promo to become visible, for example with `visibility:visible`.
await page.wait_for_selector('#promo')
```
```python-sync
```python sync
# Wait for #search to appear in the DOM.
page.wait_for_selector('#search', state='attached')
# Wait for #promo to become visible, for example with `visibility:visible`.
@ -461,14 +461,14 @@ await page.waitForSelector('#details', { state: 'hidden' });
await page.waitForSelector('#promo', { state: 'detached' });
```
```python-async
```python async
# Wait for #details to become hidden, for example with `display:none`.
await page.wait_for_selector('#details', state='hidden')
# Wait for #promo to be removed from the DOM.
await page.wait_for_selector('#promo', state='detached')
```
```python-sync
```python sync
# Wait for #details to become hidden, for example with `display:none`.
page.wait_for_selector('#details', state='hidden')
# Wait for #promo to be removed from the DOM.
@ -495,11 +495,11 @@ of the web page and bring results back to the Node.js environment. Browser globa
const href = await page.evaluate(() => document.location.href);
```
```python-async
```python async
href = await page.evaluate('() => document.location.href')
```
```python-sync
```python sync
href = page.evaluate('() => document.location.href')
```
@ -512,14 +512,14 @@ const status = await page.evaluate(async () => {
});
```
```python-async
```python async
status = await page.evaluate("""async () => {
response = await fetch(location.href)
return response.status
}""")
```
```python-sync
```python sync
status = page.evaluate("""async () => {
response = fetch(location.href)
return response.status
@ -573,7 +573,7 @@ await page.evaluate(
{ button1, list: [button2], foo: null });
```
```python-async
```python async
# A primitive value.
await page.evaluate('num => num', 42)
@ -616,7 +616,7 @@ await page.evaluate("""
{ 'button1': button1, 'list': [button2], 'foo': None })
```
```python-sync
```python sync
# A primitive value.
page.evaluate('num => num', 42)
@ -668,7 +668,7 @@ const result = await page.evaluate(data => {
}, data);
```
```python-async
```python async
data = { 'text': 'some data', 'value': 1 }
# Pass |data| as a parameter.
result = await page.evaluate("""data => {
@ -676,7 +676,7 @@ result = await page.evaluate("""data => {
}""", data)
```
```python-sync
```python sync
data = { 'text': 'some data', 'value': 1 }
# Pass |data| as a parameter.
result = page.evaluate("""data => {
@ -694,7 +694,7 @@ const result = await page.evaluate(() => {
});
```
```python-async
```python async
data = { 'text': 'some data', 'value': 1 }
result = await page.evaluate("""() => {
# There is no |data| in the web page.
@ -702,7 +702,7 @@ result = await page.evaluate("""() => {
}""")
```
```python-sync
```python sync
data = { 'text': 'some data', 'value': 1 }
result = page.evaluate("""() => {
# There is no |data| in the web page.
@ -744,13 +744,13 @@ const ulElementHandle = await page.$('ul');
await ulElementHandle.evaluate(ulElement => getComputedStyle(ulElement).getPropertyValue('display'));
```
```python-async
```python async
# The first parameter of the elementHandle.evaluate callback is the element handle points to.
ul_element_handle = await page.query_selector('ul')
await ul_element_handle.evaluate("ulElement => getComputedStyle(ulElement).getPropertyValue('display')")
```
```python-sync
```python sync
# The first parameter of the elementHandle.evaluate callback is the element handle points to.
ul_element_handle = page.query_selector('ul')
ul_element_handle.evaluate("ulElement => getComputedStyle(ulElement).getPropertyValue('display')")
@ -764,12 +764,12 @@ const ulElementHandle = await page.$('ul');
await page.evaluate(uiElement => getComputedStyle(uiElement).getPropertyValue('display'), uiElement);
```
```python-async
```python async
ul_element_handle = await page.query_selector('ul')
await page.evaluate("uiElement => getComputedStyle(uiElement).getPropertyValue('display')", uiElement)
```
```python-sync
```python sync
ul_element_handle = page.query_selector('ul')
page.evaluate("uiElement => getComputedStyle(uiElement).getPropertyValue('display')", uiElement)
```
@ -803,7 +803,7 @@ const newLength = await page.evaluate(() => window.myArray.length);
await myArrayHandle.dispose();
```
```python-async
```python async
# Create a new array in the page, write a reference to it in
# window.myArray and get a handle to it.
my_array_handle = await page.evaluate_handle("""() => {
@ -830,7 +830,7 @@ new_length = await page.evaluate("() => window.myArray.length")
await my_array_handle.dispose()
```
```python-sync
```python sync
# Create a new array in the page, write a reference to it in
# window.myArray and get a handle to it.
my_array_handle = page.evaluate_handle("""() => {

View file

@ -19,17 +19,17 @@ to slow down execution and follow along while debugging.
await chromium.launch({ headless: false, slowMo: 100 }); // or firefox, webkit
```
```python-async
```python async
await chromium.launch(headless=False, slow_mo=100) # or firefox, webkit
```
```python-sync
```python sync
chromium.launch(headless=False, slow_mo=100) # or firefox, webkit
```
## Visual Studio Code debugger
## Visual Studio Code debugger (Node.JS)
The VS Code debugger can be used to pause and resume execution of Playwright
scripts with breakpoints. The debugger can be configured in two ways.
@ -40,18 +40,13 @@ Setup [`launch.json` configuration](https://code.visualstudio.com/docs/nodejs/no
for your Node.js project. Once configured launch the scripts with F5 and use
breakpoints.
### Use the new JavaScript debugger
### Use the new JavaScript debugging terminal
VS Code 1.46+ introduces the new JavaScript debugger behind a feature flag. The
new debugger does not require a `launch.json` configuration. To use this:
1. Enable the preview debugger
* Open JSON settings and add `"debug.javascript.usePreview": true`
* Open settings UI and enable the `Debug JavaScript: Use Preview` setting
VS Code 1.46+ introduced the new JavaScript debugger that does not require a `launch.json`
configuration. To use it:
1. Set a breakpoint in VS Code
* Use the `debugger` keyword or set a breakpoint in the VS Code UI
1. Run your Node.js script from the terminal
## Browser Developer Tools
@ -76,12 +71,12 @@ In Chromium, you can also open developer tools through a launch option.
await chromium.launch({ devtools: true });
```
```python-async
```python async
await chromium.launch(devtools=True)
```
```python-sync
```python sync
chromium.launch(devtools=True)
```

View file

@ -3,7 +3,7 @@ id: docker
title: "Docker"
---
[Dockerfile.bionic](https://github.com/microsoft/playwright/blob/master/utils/docker/Dockerfile.bionic) and [Dockerfile.focal](https://github.com/microsoft/playwright/blob/master/utils/docker/Dockerfile.focal) can be used to run Playwright scripts in Docker environments. These images includes all the dependencies needed to run browsers in a Docker container, including browsers.
[Dockerfile.bionic](https://github.com/microsoft/playwright/blob/master/utils/docker/Dockerfile.bionic) and [Dockerfile.focal](https://github.com/microsoft/playwright/blob/master/utils/docker/Dockerfile.focal) can be used to run Playwright scripts in Docker environments. These images includes all the dependencies needed to run browsers in a Docker container, and also include the browsers themselves.
<!-- TOC -->

View file

@ -29,7 +29,7 @@ const context = await browser.newContext({
});
```
```python-async
```python async
import asyncio
from playwright import async_playwright
@ -44,7 +44,7 @@ async def main():
asyncio.get_event_loop().run_until_complete(main())
```
```python-sync
```python sync
from playwright import sync_playwright
with sync_playwright() as p:
@ -74,13 +74,13 @@ const context = await browser.newContext({
});
```
```python-async
```python async
context = await browser.new_context(
user_agent='My user agent'
)
```
```python-sync
```python sync
context = browser.new_context(
user_agent='My user agent'
)
@ -112,7 +112,7 @@ const context = await browser.newContext({
});
```
```python-async
```python async
# Create context with given viewport
context = await browser.new_context(
viewport={ 'width': 1280, 'height': 1024 }
@ -128,7 +128,7 @@ context = await browser.new_context(
)
```
```python-sync
```python sync
# Create context with given viewport
context = browser.new_context(
viewport={ 'width': 1280, 'height': 1024 }
@ -161,7 +161,7 @@ const context = await browser.newContext({
});
```
```python-async
```python async
# Emulate locale and time
context = await browser.new_context(
locale='de-DE',
@ -169,7 +169,7 @@ context = await browser.new_context(
)
```
```python-sync
```python sync
# Emulate locale and time
context = browser.new_context(
locale='de-DE',
@ -193,13 +193,13 @@ const context = await browser.newContext({
});
```
```python-async
```python async
context = await browser.new_context(
permissions=['notifications'],
)
```
```python-sync
```python sync
context = browser.new_context(
permissions=['notifications'],
)
@ -211,11 +211,11 @@ Grant all pages in the existing context access to current location:
await context.grantPermissions(['geolocation']);
```
```python-async
```python async
await context.grant_permissions(['geolocation'])
```
```python-sync
```python sync
context.grant_permissions(['geolocation'])
```
@ -225,11 +225,11 @@ Grant notifications access from a specific domain:
await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
```
```python-async
```python async
await context.grant_permissions(['notifications'], origin='https://skype.com')
```
```python-sync
```python sync
context.grant_permissions(['notifications'], origin='https://skype.com')
```
@ -239,11 +239,11 @@ Revoke all permissions:
await context.clearPermissions();
```
```python-async
```python async
await context.clear_permissions()
```
```python-sync
```python sync
context.clear_permissions()
```
@ -265,14 +265,14 @@ const context = await browser.newContext({
});
```
```python-async
```python async
context = await browser.new_context(
geolocation={"longitude": 48.858455, "latitude": 2.294474},
permissions=["geolocation"]
)
```
```python-sync
```python sync
context = browser.new_context(
geolocation={"longitude": 48.858455, "latitude": 2.294474},
permissions=["geolocation"]
@ -285,11 +285,11 @@ Change the location later:
await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 });
```
```python-async
```python async
await context.set_geolocation({"longitude": 29.979097, "latitude": 31.134256})
```
```python-sync
```python sync
context.set_geolocation({"longitude": 29.979097, "latitude": 31.134256})
```
@ -325,7 +325,7 @@ await page.emulateMedia({ colorScheme: 'dark' });
await page.emulateMedia({ media: 'print' });
```
```python-async
```python async
# Create context with dark mode
context = await browser.new_context(
color_scheme='dark' # or 'light'
@ -343,7 +343,7 @@ await page.emulate_media(color_scheme='dark')
await page.emulate_media(media='print')
```
```python-sync
```python sync
# Create context with dark mode
context = browser.new_context(
color_scheme='dark' # or 'light'

View file

@ -26,7 +26,7 @@ await page.fill('#local', '2020-03-02T05:15');
await page.fill('text=First Name', 'Peter');
```
```python-async
```python async
# Text input
await page.fill('#name', 'Peter')
@ -43,7 +43,7 @@ await page.fill('#local', '2020-03-02T05:15')
await page.fill('text=First Name', 'Peter')
```
```python-sync
```python sync
# Text input
page.fill('#name', 'Peter')
@ -83,7 +83,7 @@ await page.uncheck('#subscribe-label');
await page.check('text=XL');
```
```python-async
```python async
# Check the checkbox
await page.check('#agree')
@ -94,7 +94,7 @@ await page.uncheck('#subscribe-label')
await page.check('text=XL')
```
```python-sync
```python sync
# Check the checkbox
page.check('#agree')
@ -136,7 +136,7 @@ const option = await page.$('#best-option');
await page.selectOption('select#colors', option);
```
```python-async
```python async
# Single selection matching the value
await page.select_option('select#colors', 'blue')
@ -151,7 +151,7 @@ option = await page.query_selector('#best-option')
await page.select_option('select#colors', option)
```
```python-sync
```python sync
# Single selection matching the value
page.select_option('select#colors', 'blue')
@ -198,7 +198,7 @@ await page.hover('#item');
await page.click('#item', { position: { x: 0, y: 0} });
```
```python-async
```python async
# Generic click
await page.click('button#submit')
@ -218,7 +218,7 @@ await page.hover('#item')
await page.click('#item', position={ 'x': 0, 'y': 0})
```
```python-sync
```python sync
# Generic click
page.click('button#submit')
@ -255,11 +255,11 @@ Sometimes, apps use non-trivial logic where hovering the element overlays it wit
await page.click('button#submit', { force: true });
```
```python-async
```python async
await page.click('button#submit', force=True)
```
```python-sync
```python sync
page.click('button#submit', force=True)
```
@ -271,11 +271,11 @@ If you are not interested in testing your app under the real conditions and want
await page.dispatchEvent('button#submit', 'click');
```
```python-async
```python async
await page.dispatch_event('button#submit', 'click')
```
```python-sync
```python sync
page.dispatch_event('button#submit', 'click')
```
@ -305,12 +305,12 @@ Type into the field character by character, as if it was a user with a real keyb
await page.type('#area', 'Hello World!');
```
```python-async
```python async
# Type character by character
await page.type('#area', 'Hello World!')
```
```python-sync
```python sync
# Type character by character
page.type('#area', 'Hello World!')
```
@ -341,7 +341,7 @@ await page.press('#name', 'Control+ArrowRight');
await page.press('#value', '$');
```
```python-async
```python async
# Hit Enter
await page.press('#submit', 'Enter')
@ -352,7 +352,7 @@ await page.press('#name', 'Control+ArrowRight')
await page.press('#value', '$')
```
```python-sync
```python sync
# Hit Enter
page.press('#submit', 'Enter')
@ -386,7 +386,7 @@ await page.press('#name', 'Shift+A');
await page.press('#name', 'Shift+ArrowLeft');
```
```python-async
```python async
# <input id=name>
await page.press('#name', 'Shift+A')
@ -394,7 +394,7 @@ await page.press('#name', 'Shift+A')
await page.press('#name', 'Shift+ArrowLeft')
```
```python-sync
```python sync
# <input id=name>
page.press('#name', 'Shift+A')
@ -436,7 +436,7 @@ await page.setInputFiles('input#upload', {
});
```
```python-async
```python async
from playwright.async_api import FilePayload
# Select one file
await page.set_input_files('input#upload', 'myfile.pdf')
@ -454,7 +454,7 @@ await page.set_input_files(
)
```
```python-sync
```python sync
from playwright.sync_api import FilePayload
# Select one file
page.set_input_files('input#upload', 'myfile.pdf')
@ -494,11 +494,11 @@ For the dynamic pages that handle focus events, you can focus the given element.
await page.focus('input#name');
```
```python-async
```python async
await page.focus('input#name')
```
```python-sync
```python sync
page.focus('input#name')
```

View file

@ -1,6 +1,6 @@
---
id: installation
title: "Advanced installation"
title: "Installation"
---
<!-- TOC -->

86
docs/src/intro-python.md Normal file
View file

@ -0,0 +1,86 @@
---
id: intro-python
title: "Getting Started"
---
<!-- TOC -->
## Installation
Use pip to install Playwright in your Python project. See [system requirements](#system-requirements).
```sh
pip install playwright
python -m playwright install
```
These commands download the Playwright package and install browser binaries for Chromium, Firefox and WebKit. To modify this behavior see [installation parameters](./installation.md).
## Usage
Once installed, you can `import` Playwright in a Python script, and launch any of the 3 browsers (`chromium`, `firefox` and `webkit`).
```python
from playwright import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
# interact with UI elements, assert values
browser.close()
```
Playwright supports two variations of the API: synchronous are asynchronous. If your modern project uses
[asyncio](https://docs.python.org/3/library/asyncio.html), you should use async API:
```python
from playwright import async_playwright
with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
# interact with UI elements, assert values
await browser.close()
```
## First script
In our first script, we will navigate to `whatsmyuseragent.org` and take a screenshot in WebKit.
```python
from playwright import sync_playwright
with sync_playwright() as p:
browser = p.webkit.launch()
page = await browser.new_page()
page.goto("http://whatsmyuseragent.org/")
page.screenshot(path="example.png")
browser.close()
```
By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless=False` flag while launching the browser. You can also use `slowMo` to slow down execution. Learn more in the debugging tools [section](./debug.md).
```python
firefox.launch(headless=False, slowMo=50)
```
## Record scripts
Command Line Interface [CLI](./cli.md) can be used to record user interactions and generate Python code.
```sh
python -m playwright codegen wikipedia.org
```
## System requirements
Playwright requires Python version 3.7 or above. The browser binaries for Chromium,
Firefox and WebKit work across the 3 platforms (Windows, macOS, Linux):
* **Windows**: Works with Windows and Windows Subsystem for Linux (WSL).
* **macOS**: Requires 10.14 or above.
* **Linux**: Depending on your Linux distribution, you might need to install additional
dependencies to run the browsers.
* Firefox requires Ubuntu 18.04+
* For Ubuntu 18.04, the additional dependencies are defined in [our Docker image](https://github.com/microsoft/playwright/blob/master/utils/docker/Dockerfile.bionic),
which is based on Ubuntu.

View file

@ -54,7 +54,7 @@ const { webkit } = require('playwright');
})();
```
By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless: false` flag while launching the browser. You can also use `slowMo` to slow down execution.
By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless: false` flag while launching the browser. You can also use `slowMo` to slow down execution. Learn more in the debugging tools [section](./debug.md).
```js
firefox.launch({ headless: false, slowMo: 50 });
@ -62,7 +62,7 @@ firefox.launch({ headless: false, slowMo: 50 });
## Record scripts
[Playwright CLI](./cli.md) can be used to record user interactions and generate JavaScript code.
Command Line Interface [CLI](./cli.md) can be used to record user interactions and generate JavaScript code.
```sh
npx playwright codegen wikipedia.org

View file

@ -0,0 +1,210 @@
---
id: test-runners-python
title: "Test Runners"
---
You can use our [Pytest integration](https://github.com/microsoft/playwright-pytest) to write end-to-end tests
in Python.
<!-- TOC -->
## Usage
```sh
pip install pytest-playwright
```
Use the `page` fixture to write a basic test. See [more examples](#examples).
```py
def test_example_is_working(page):
page.goto("https://example.com")
assert page.innerText('h1') == 'Example Domain'
page.click("text=More information")
```
To run your tests, use pytest CLI.
```sh
# Run tests (Chromium and headless by default)
pytest
# Run tests in headful mode
pytest --headful
# Run tests in a different browser (chromium, firefox, webkit)
pytest --browser firefox
# Run tests in multiple browsers
pytest --browser chromium --browser webkit
```
If you want to add the CLI arguments automatically without specifying them, you can use the [pytest.ini](https://docs.pytest.org/en/stable/reference.html#ini-options-ref) file:
```ini
# content of pytest.ini
[pytest]
# Run firefox with UI
addopts = --headful --browser firefox
```
## Fixtures
This plugin configures Playwright-specific [fixtures for pytest](https://docs.pytest.org/en/latest/fixture.html). To use these fixtures, use the fixture name as an argument to the test function.
```py
def test_my_app_is_working(fixture_name):
# Test using fixture_name
# ...
```
**Function scope**: These fixtures are created when requested in a test function and destroyed when the test ends.
- `context`: New [browser context](https://playwright.dev/#path=docs%2Fcore-concepts.md&q=browser-contexts) for a test.
- `page`: New [browser page](https://playwright.dev/#path=docs%2Fcore-concepts.md&q=pages-and-frames) for a test.
**Session scope**: These fixtures are created when requested in a test function and destroyed when all tests end.
- `browser`: Browser instance launched by Playwright.
- `browser_name`: Browser name as string.
- `is_chromium`, `is_webkit`, `is_firefox`: Booleans for the respective browser types.
**Customizing fixture options**: For `browser` and `context` fixtures, use the the following fixtures to define custom launch options.
- `browser_type_launch_args`: Override launch arguments for [`browserType.launch()`](https://playwright.dev/#path=docs%2Fapi.md&q=browsertypelaunchoptions). It should return a Dict.
- `browser_context_args`: Override the options for [`browser.newContext()`](https://playwright.dev/#path=docs%2Fapi.md&q=browsernewcontextoptions). It should return a Dict.
## Examples
### Configure Mypy typings for auto-completion
```py
from playwright.sync_api import Page
def test_visit_admin_dashboard(page: Page):
page.goto("/admin")
# ...
```
### Skip test by browser
```py
import pytest
@pytest.mark.skip_browser("firefox")
def test_visit_example(page):
page.goto("https://example.com")
# ...
```
### Run on a specific browser
```py
import pytest
@pytest.mark.only_browser("chromium")
def test_visit_example(page):
page.goto("https://example.com")
# ...
```
### Configure base-url
Start Pytest with the `base-url` argument.
```sh
pytest --base-url http://localhost:8080
```
```py
def test_visit_example(page):
page.goto("/admin")
# -> Will result in http://localhost:8080/admin
```
### Ignore HTTPS errors
conftest.py
```py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"ignoreHTTPSErrors": True
}
```
### Use custom viewport size
conftest.py
```py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
return {
**browser_context_args,
"viewport": {
"width": 1920,
"height": 1080,
}
}
```
### Device emulation
conftest.py
```py
import pytest
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, playwright):
iphone_11 = playwright.devices['iPhone 11 Pro']
return {
**browser_context_args,
**iphone_11,
}
```
## Debugging
### Use with pdb
Use the `breakpoint()` statement in your test code to pause execution and get a [pdb](https://docs.python.org/3/library/pdb.html) REPL.
```py
def test_bing_is_working(page):
page.goto("https://bing.com")
breakpoint()
# ...
```
### Screenshot on test failure
You can capture screenshots for failed tests with a [pytest runtest hook](https://docs.pytest.org/en/6.1.0/reference.html?highlight=pytest_runtest_makereport#test-running-runtest-hooks). Add this to your `conftest.py` file.
Note that this snippet uses `slugify` to convert test names to file paths, which can be installed with `pip install python-slugify`.
```py
# In conftest.py
from slugify import slugify
from pathlib import Path
def pytest_runtest_makereport(item, call) -> None:
if call.when == "call":
if call.excinfo is not None and "page" in item.funcargs:
page = item.funcargs["page"]
screenshot_dir = Path(".playwright-screenshots")
screenshot_dir.mkdir(exist_ok=True)
page.screenshot(path=str(screenshot_dir / f"{slugify(item.nodeid)}.png"))
```
## Deploy to CI
Use the [Playwright GitHub Action](https://github.com/microsoft/playwright-github-action) or [guides for other CI providers](https://playwright.dev/#path=docs%2Fci.md&q=) to deploy your tests to CI/CD

View file

@ -41,7 +41,8 @@ Playwright enables fast, reliable and capable automation across all modern brows
* **Debugging tools**. Playwright works with the [editor debugger and browser developer tools](./debug.md) to pause execution and inspect the web page.
* **Language bindings**. Playwright is also available in [Python](https://github.com/microsoft/playwright-python) and [C#](https://github.com/microsoft/playwright-sharp). Learn about [supported languages](./languages.md).
* **Language bindings**. Playwright is available for [Node.js](https://github.com/microsoft/playwright) [Python](https://github.com/microsoft/playwright-python), [C#](https://github.com/microsoft/playwright-sharp) and
[Java](https://github.com/microsoft/playwright-java). Learn more about [supported languages](./languages.md).
* **Deploy tests to CI**. First-party [Docker image](./docker.md) and [GitHub Actions](https://github.com/microsoft/playwright-github-action) to deploy tests to [your preferred CI/CD provider](./ci.md).

View file

@ -342,7 +342,7 @@ function generateToc(nodes) {
if (node.type === 'h1' || node.type === 'h2') {
let link = node.text.toLowerCase();
link = link.replace(/[ ]+/g, '-');
link = link.replace(/[^\w-]/g, '');
link = link.replace(/[^\w-_]/g, '');
result.push(`${' '.repeat(depth * 2)}- [${node.text}](#${link})`);
}
});