Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions playwright/_impl/_browser_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ async def launch_persistent_context(
raise e

async def connect_over_cdp(
self, endpointURL: str, timeout: float = None, slow_mo: float = None
self,
endpointURL: str,
timeout: float = None,
slow_mo: float = None,
headers: Dict[str, str] = None,
) -> Browser:
params = locals_to_params(locals())
params["sdkLanguage"] = (
Expand All @@ -162,9 +166,13 @@ async def connect_over_cdp(
return browser

async def connect(
self, ws_endpoint: str, timeout: float = None, slow_mo: float = None
self,
ws_endpoint: str,
timeout: float = None,
slow_mo: float = None,
headers: Dict[str, str] = None,
) -> Browser:
transport = WebSocketTransport(ws_endpoint, timeout)
transport = WebSocketTransport(ws_endpoint, timeout, headers)

connection = Connection(
self._connection._dispatcher_fiber,
Expand Down
9 changes: 7 additions & 2 deletions playwright/_impl/_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,16 @@ def send(self, message: Dict) -> None:


class WebSocketTransport(AsyncIOEventEmitter, Transport):
def __init__(self, ws_endpoint: str, timeout: float = None) -> None:
def __init__(
self, ws_endpoint: str, timeout: float = None, headers: Dict[str, str] = None
) -> None:
super().__init__()
Transport.__init__(self)

self._stopped = False
self.ws_endpoint = ws_endpoint
self.timeout = timeout
self.headers = headers
self._loop: asyncio.AbstractEventLoop

def request_stop(self) -> None:
Expand All @@ -159,10 +162,12 @@ async def wait_until_stopped(self) -> None:
async def run(self) -> None:
await super().run()

options = {}
options: Dict[str, Any] = {}
if self.timeout is not None:
options["close_timeout"] = self.timeout / 1000
options["ping_timeout"] = self.timeout / 1000
if self.headers is not None:
options["extra_headers"] = self.headers
self._connection = await websockets.connect(self.ws_endpoint, **options)

while not self._stopped:
Expand Down
60 changes: 53 additions & 7 deletions playwright/async_api/_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ async def handle(route, request):
\"foo\": \"bar\" # set \"foo\" header
\"origin\": None # remove \"origin\" header
}
await route.continue(headers=headers)
await route.continue_(headers=headers)
}
await page.route(\"**/*\", handle)
```
Expand Down Expand Up @@ -6384,6 +6384,18 @@ async def route(
await browser.close()
```

It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
post data, and leaving all other requests as is:

```py
def handle_route(route):
if (\"my-string\" in route.request.post_data)
route.fulfill(body=\"mocked-data\")
else
route.continue_()
await page.route(\"/api/**\", handle_route)
```

Page routes take precedence over browser context routes (set up with `browser_context.route()`) when request
matches both handlers.

Expand Down Expand Up @@ -7865,13 +7877,15 @@ def expect_request(
) -> AsyncEventContextManager["Request"]:
"""Page.expect_request

Waits for the matching request and returns it.
Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details
about events.

```py
async with page.expect_request(\"http://example.com/resource\") as first:
await page.click('button')
first_request = await first.value

# or with a lambda
async with page.expect_request(lambda request: request.url == \"http://example.com\" and request.method == \"get\") as second:
await page.click('img')
second_request = await second.value
Expand Down Expand Up @@ -7906,7 +7920,7 @@ def expect_response(
) -> AsyncEventContextManager["Response"]:
"""Page.expect_response

Returns the matched response.
Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events.

```py
async with page.expect_response(\"https://example.com/resource\") as response_info:
Expand Down Expand Up @@ -8481,6 +8495,18 @@ async def route(
await browser.close()
```

It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
post data, and leaving all other requests as is:

```py
def handle_route(route):
if (\"my-string\" in route.request.post_data)
route.fulfill(body=\"mocked-data\")
else
route.continue_()
await context.route(\"/api/**\", handle_route)
```

Page routes (set up with `page.route()`) take precedence over browser context routes when request matches both
handlers.

Expand Down Expand Up @@ -9567,7 +9593,12 @@ async def launch_persistent_context(
)

async def connect_over_cdp(
self, endpoint_url: str, *, timeout: float = None, slow_mo: float = None
self,
endpoint_url: str,
*,
timeout: float = None,
slow_mo: float = None,
headers: typing.Optional[typing.Dict[str, str]] = None
) -> "Browser":
"""BrowserType.connect_over_cdp

Expand All @@ -9588,6 +9619,8 @@ async def connect_over_cdp(
slow_mo : Union[float, NoneType]
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
Defaults to 0.
headers : Union[Dict[str, str], NoneType]
Additional HTTP headers to be sent with connect request. Optional.

Returns
-------
Expand All @@ -9598,13 +9631,21 @@ async def connect_over_cdp(
await self._async(
"browser_type.connect_over_cdp",
self._impl_obj.connect_over_cdp(
endpointURL=endpoint_url, timeout=timeout, slow_mo=slow_mo
endpointURL=endpoint_url,
timeout=timeout,
slow_mo=slow_mo,
headers=mapping.to_impl(headers),
),
)
)

async def connect(
self, ws_endpoint: str, *, timeout: float = None, slow_mo: float = None
self,
ws_endpoint: str,
*,
timeout: float = None,
slow_mo: float = None,
headers: typing.Optional[typing.Dict[str, str]] = None
) -> "Browser":
"""BrowserType.connect

Expand All @@ -9620,6 +9661,8 @@ async def connect(
slow_mo : Union[float, NoneType]
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
Defaults to 0.
headers : Union[Dict[str, str], NoneType]
Additional HTTP headers to be sent with web socket connect request. Optional.

Returns
-------
Expand All @@ -9630,7 +9673,10 @@ async def connect(
await self._async(
"browser_type.connect",
self._impl_obj.connect(
ws_endpoint=ws_endpoint, timeout=timeout, slow_mo=slow_mo
ws_endpoint=ws_endpoint,
timeout=timeout,
slow_mo=slow_mo,
headers=mapping.to_impl(headers),
),
)
)
Expand Down
60 changes: 53 additions & 7 deletions playwright/sync_api/_generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ def handle(route, request):
\"foo\": \"bar\" # set \"foo\" header
\"origin\": None # remove \"origin\" header
}
route.continue(headers=headers)
route.continue_(headers=headers)
}
page.route(\"**/*\", handle)
```
Expand Down Expand Up @@ -6345,6 +6345,18 @@ def route(
browser.close()
```

It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
post data, and leaving all other requests as is:

```py
def handle_route(route):
if (\"my-string\" in route.request.post_data)
route.fulfill(body=\"mocked-data\")
else
route.continue_()
page.route(\"/api/**\", handle_route)
```

Page routes take precedence over browser context routes (set up with `browser_context.route()`) when request
matches both handlers.

Expand Down Expand Up @@ -7819,13 +7831,15 @@ def expect_request(
) -> EventContextManager["Request"]:
"""Page.expect_request

Waits for the matching request and returns it.
Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details
about events.

```py
with page.expect_request(\"http://example.com/resource\") as first:
page.click('button')
first_request = first.value

# or with a lambda
with page.expect_request(lambda request: request.url == \"http://example.com\" and request.method == \"get\") as second:
page.click('img')
second_request = second.value
Expand Down Expand Up @@ -7860,7 +7874,7 @@ def expect_response(
) -> EventContextManager["Response"]:
"""Page.expect_response

Returns the matched response.
Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events.

```py
with page.expect_response(\"https://example.com/resource\") as response_info:
Expand Down Expand Up @@ -8427,6 +8441,18 @@ def route(
browser.close()
```

It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
post data, and leaving all other requests as is:

```py
def handle_route(route):
if (\"my-string\" in route.request.post_data)
route.fulfill(body=\"mocked-data\")
else
route.continue_()
context.route(\"/api/**\", handle_route)
```

Page routes (set up with `page.route()`) take precedence over browser context routes when request matches both
handlers.

Expand Down Expand Up @@ -9513,7 +9539,12 @@ def launch_persistent_context(
)

def connect_over_cdp(
self, endpoint_url: str, *, timeout: float = None, slow_mo: float = None
self,
endpoint_url: str,
*,
timeout: float = None,
slow_mo: float = None,
headers: typing.Optional[typing.Dict[str, str]] = None
) -> "Browser":
"""BrowserType.connect_over_cdp

Expand All @@ -9534,6 +9565,8 @@ def connect_over_cdp(
slow_mo : Union[float, NoneType]
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
Defaults to 0.
headers : Union[Dict[str, str], NoneType]
Additional HTTP headers to be sent with connect request. Optional.

Returns
-------
Expand All @@ -9544,13 +9577,21 @@ def connect_over_cdp(
self._sync(
"browser_type.connect_over_cdp",
self._impl_obj.connect_over_cdp(
endpointURL=endpoint_url, timeout=timeout, slow_mo=slow_mo
endpointURL=endpoint_url,
timeout=timeout,
slow_mo=slow_mo,
headers=mapping.to_impl(headers),
),
)
)

def connect(
self, ws_endpoint: str, *, timeout: float = None, slow_mo: float = None
self,
ws_endpoint: str,
*,
timeout: float = None,
slow_mo: float = None,
headers: typing.Optional[typing.Dict[str, str]] = None
) -> "Browser":
"""BrowserType.connect

Expand All @@ -9566,6 +9607,8 @@ def connect(
slow_mo : Union[float, NoneType]
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
Defaults to 0.
headers : Union[Dict[str, str], NoneType]
Additional HTTP headers to be sent with web socket connect request. Optional.

Returns
-------
Expand All @@ -9576,7 +9619,10 @@ def connect(
self._sync(
"browser_type.connect",
self._impl_obj.connect(
ws_endpoint=ws_endpoint, timeout=timeout, slow_mo=slow_mo
ws_endpoint=ws_endpoint,
timeout=timeout,
slow_mo=slow_mo,
headers=mapping.to_impl(headers),
),
)
)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
InWheel = None
from wheel.bdist_wheel import bdist_wheel as BDistWheelCommand

driver_version = "1.11.0-next-1619111599000"
driver_version = "1.11.0-next-1619452681000"


def extractall(zip: zipfile.ZipFile, path: str) -> None:
Expand Down
2 changes: 1 addition & 1 deletion tests/async/test_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ async def test_should_error_when_saving_after_deletion(tmpdir, browser, server):
await download.delete()
with pytest.raises(Error) as exc:
await download.save_as(user_path)
assert "File already deleted. Save before deleting." in exc.value.message
assert "Target page, context or browser has been closed" in exc.value.message
await page.close()


Expand Down