Skip to content

Commit 027c1fb

Browse files
chore: added headers param for BrowserType.connect (#648)
1 parent 890a833 commit 027c1fb

File tree

6 files changed

+126
-21
lines changed

6 files changed

+126
-21
lines changed

playwright/_impl/_browser_type.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ async def launch_persistent_context(
142142
raise e
143143

144144
async def connect_over_cdp(
145-
self, endpointURL: str, timeout: float = None, slow_mo: float = None
145+
self,
146+
endpointURL: str,
147+
timeout: float = None,
148+
slow_mo: float = None,
149+
headers: Dict[str, str] = None,
146150
) -> Browser:
147151
params = locals_to_params(locals())
148152
params["sdkLanguage"] = (
@@ -162,9 +166,13 @@ async def connect_over_cdp(
162166
return browser
163167

164168
async def connect(
165-
self, ws_endpoint: str, timeout: float = None, slow_mo: float = None
169+
self,
170+
ws_endpoint: str,
171+
timeout: float = None,
172+
slow_mo: float = None,
173+
headers: Dict[str, str] = None,
166174
) -> Browser:
167-
transport = WebSocketTransport(ws_endpoint, timeout)
175+
transport = WebSocketTransport(ws_endpoint, timeout, headers)
168176

169177
connection = Connection(
170178
self._connection._dispatcher_fiber,

playwright/_impl/_transport.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,16 @@ def send(self, message: Dict) -> None:
137137

138138

139139
class WebSocketTransport(AsyncIOEventEmitter, Transport):
140-
def __init__(self, ws_endpoint: str, timeout: float = None) -> None:
140+
def __init__(
141+
self, ws_endpoint: str, timeout: float = None, headers: Dict[str, str] = None
142+
) -> None:
141143
super().__init__()
142144
Transport.__init__(self)
143145

144146
self._stopped = False
145147
self.ws_endpoint = ws_endpoint
146148
self.timeout = timeout
149+
self.headers = headers
147150
self._loop: asyncio.AbstractEventLoop
148151

149152
def request_stop(self) -> None:
@@ -159,10 +162,12 @@ async def wait_until_stopped(self) -> None:
159162
async def run(self) -> None:
160163
await super().run()
161164

162-
options = {}
165+
options: Dict[str, Any] = {}
163166
if self.timeout is not None:
164167
options["close_timeout"] = self.timeout / 1000
165168
options["ping_timeout"] = self.timeout / 1000
169+
if self.headers is not None:
170+
options["extra_headers"] = self.headers
166171
self._connection = await websockets.connect(self.ws_endpoint, **options)
167172

168173
while not self._stopped:

playwright/async_api/_generated.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ async def handle(route, request):
560560
\"foo\": \"bar\" # set \"foo\" header
561561
\"origin\": None # remove \"origin\" header
562562
}
563-
await route.continue(headers=headers)
563+
await route.continue_(headers=headers)
564564
}
565565
await page.route(\"**/*\", handle)
566566
```
@@ -6384,6 +6384,18 @@ async def route(
63846384
await browser.close()
63856385
```
63866386
6387+
It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
6388+
post data, and leaving all other requests as is:
6389+
6390+
```py
6391+
def handle_route(route):
6392+
if (\"my-string\" in route.request.post_data)
6393+
route.fulfill(body=\"mocked-data\")
6394+
else
6395+
route.continue_()
6396+
await page.route(\"/api/**\", handle_route)
6397+
```
6398+
63876399
Page routes take precedence over browser context routes (set up with `browser_context.route()`) when request
63886400
matches both handlers.
63896401
@@ -7865,13 +7877,15 @@ def expect_request(
78657877
) -> AsyncEventContextManager["Request"]:
78667878
"""Page.expect_request
78677879
7868-
Waits for the matching request and returns it.
7880+
Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details
7881+
about events.
78697882
78707883
```py
78717884
async with page.expect_request(\"http://example.com/resource\") as first:
78727885
await page.click('button')
78737886
first_request = await first.value
78747887
7888+
# or with a lambda
78757889
async with page.expect_request(lambda request: request.url == \"http://example.com\" and request.method == \"get\") as second:
78767890
await page.click('img')
78777891
second_request = await second.value
@@ -7906,7 +7920,7 @@ def expect_response(
79067920
) -> AsyncEventContextManager["Response"]:
79077921
"""Page.expect_response
79087922
7909-
Returns the matched response.
7923+
Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events.
79107924
79117925
```py
79127926
async with page.expect_response(\"https://example.com/resource\") as response_info:
@@ -8481,6 +8495,18 @@ async def route(
84818495
await browser.close()
84828496
```
84838497
8498+
It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
8499+
post data, and leaving all other requests as is:
8500+
8501+
```py
8502+
def handle_route(route):
8503+
if (\"my-string\" in route.request.post_data)
8504+
route.fulfill(body=\"mocked-data\")
8505+
else
8506+
route.continue_()
8507+
await context.route(\"/api/**\", handle_route)
8508+
```
8509+
84848510
Page routes (set up with `page.route()`) take precedence over browser context routes when request matches both
84858511
handlers.
84868512
@@ -9567,7 +9593,12 @@ async def launch_persistent_context(
95679593
)
95689594

95699595
async def connect_over_cdp(
9570-
self, endpoint_url: str, *, timeout: float = None, slow_mo: float = None
9596+
self,
9597+
endpoint_url: str,
9598+
*,
9599+
timeout: float = None,
9600+
slow_mo: float = None,
9601+
headers: typing.Optional[typing.Dict[str, str]] = None
95719602
) -> "Browser":
95729603
"""BrowserType.connect_over_cdp
95739604
@@ -9588,6 +9619,8 @@ async def connect_over_cdp(
95889619
slow_mo : Union[float, NoneType]
95899620
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
95909621
Defaults to 0.
9622+
headers : Union[Dict[str, str], NoneType]
9623+
Additional HTTP headers to be sent with connect request. Optional.
95919624
95929625
Returns
95939626
-------
@@ -9598,13 +9631,21 @@ async def connect_over_cdp(
95989631
await self._async(
95999632
"browser_type.connect_over_cdp",
96009633
self._impl_obj.connect_over_cdp(
9601-
endpointURL=endpoint_url, timeout=timeout, slow_mo=slow_mo
9634+
endpointURL=endpoint_url,
9635+
timeout=timeout,
9636+
slow_mo=slow_mo,
9637+
headers=mapping.to_impl(headers),
96029638
),
96039639
)
96049640
)
96059641

96069642
async def connect(
9607-
self, ws_endpoint: str, *, timeout: float = None, slow_mo: float = None
9643+
self,
9644+
ws_endpoint: str,
9645+
*,
9646+
timeout: float = None,
9647+
slow_mo: float = None,
9648+
headers: typing.Optional[typing.Dict[str, str]] = None
96089649
) -> "Browser":
96099650
"""BrowserType.connect
96109651
@@ -9620,6 +9661,8 @@ async def connect(
96209661
slow_mo : Union[float, NoneType]
96219662
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
96229663
Defaults to 0.
9664+
headers : Union[Dict[str, str], NoneType]
9665+
Additional HTTP headers to be sent with web socket connect request. Optional.
96239666
96249667
Returns
96259668
-------
@@ -9630,7 +9673,10 @@ async def connect(
96309673
await self._async(
96319674
"browser_type.connect",
96329675
self._impl_obj.connect(
9633-
ws_endpoint=ws_endpoint, timeout=timeout, slow_mo=slow_mo
9676+
ws_endpoint=ws_endpoint,
9677+
timeout=timeout,
9678+
slow_mo=slow_mo,
9679+
headers=mapping.to_impl(headers),
96349680
),
96359681
)
96369682
)

playwright/sync_api/_generated.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ def handle(route, request):
560560
\"foo\": \"bar\" # set \"foo\" header
561561
\"origin\": None # remove \"origin\" header
562562
}
563-
route.continue(headers=headers)
563+
route.continue_(headers=headers)
564564
}
565565
page.route(\"**/*\", handle)
566566
```
@@ -6345,6 +6345,18 @@ def route(
63456345
browser.close()
63466346
```
63476347
6348+
It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
6349+
post data, and leaving all other requests as is:
6350+
6351+
```py
6352+
def handle_route(route):
6353+
if (\"my-string\" in route.request.post_data)
6354+
route.fulfill(body=\"mocked-data\")
6355+
else
6356+
route.continue_()
6357+
page.route(\"/api/**\", handle_route)
6358+
```
6359+
63486360
Page routes take precedence over browser context routes (set up with `browser_context.route()`) when request
63496361
matches both handlers.
63506362
@@ -7819,13 +7831,15 @@ def expect_request(
78197831
) -> EventContextManager["Request"]:
78207832
"""Page.expect_request
78217833
7822-
Waits for the matching request and returns it.
7834+
Waits for the matching request and returns it. See [waiting for event](./events.md#waiting-for-event) for more details
7835+
about events.
78237836
78247837
```py
78257838
with page.expect_request(\"http://example.com/resource\") as first:
78267839
page.click('button')
78277840
first_request = first.value
78287841
7842+
# or with a lambda
78297843
with page.expect_request(lambda request: request.url == \"http://example.com\" and request.method == \"get\") as second:
78307844
page.click('img')
78317845
second_request = second.value
@@ -7860,7 +7874,7 @@ def expect_response(
78607874
) -> EventContextManager["Response"]:
78617875
"""Page.expect_response
78627876
7863-
Returns the matched response.
7877+
Returns the matched response. See [waiting for event](./events.md#waiting-for-event) for more details about events.
78647878
78657879
```py
78667880
with page.expect_response(\"https://example.com/resource\") as response_info:
@@ -8427,6 +8441,18 @@ def route(
84278441
browser.close()
84288442
```
84298443
8444+
It is possible to examine the request to decide the route action. For example, mocking all requests that contain some
8445+
post data, and leaving all other requests as is:
8446+
8447+
```py
8448+
def handle_route(route):
8449+
if (\"my-string\" in route.request.post_data)
8450+
route.fulfill(body=\"mocked-data\")
8451+
else
8452+
route.continue_()
8453+
context.route(\"/api/**\", handle_route)
8454+
```
8455+
84308456
Page routes (set up with `page.route()`) take precedence over browser context routes when request matches both
84318457
handlers.
84328458
@@ -9513,7 +9539,12 @@ def launch_persistent_context(
95139539
)
95149540

95159541
def connect_over_cdp(
9516-
self, endpoint_url: str, *, timeout: float = None, slow_mo: float = None
9542+
self,
9543+
endpoint_url: str,
9544+
*,
9545+
timeout: float = None,
9546+
slow_mo: float = None,
9547+
headers: typing.Optional[typing.Dict[str, str]] = None
95179548
) -> "Browser":
95189549
"""BrowserType.connect_over_cdp
95199550
@@ -9534,6 +9565,8 @@ def connect_over_cdp(
95349565
slow_mo : Union[float, NoneType]
95359566
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
95369567
Defaults to 0.
9568+
headers : Union[Dict[str, str], NoneType]
9569+
Additional HTTP headers to be sent with connect request. Optional.
95379570
95389571
Returns
95399572
-------
@@ -9544,13 +9577,21 @@ def connect_over_cdp(
95449577
self._sync(
95459578
"browser_type.connect_over_cdp",
95469579
self._impl_obj.connect_over_cdp(
9547-
endpointURL=endpoint_url, timeout=timeout, slow_mo=slow_mo
9580+
endpointURL=endpoint_url,
9581+
timeout=timeout,
9582+
slow_mo=slow_mo,
9583+
headers=mapping.to_impl(headers),
95489584
),
95499585
)
95509586
)
95519587

95529588
def connect(
9553-
self, ws_endpoint: str, *, timeout: float = None, slow_mo: float = None
9589+
self,
9590+
ws_endpoint: str,
9591+
*,
9592+
timeout: float = None,
9593+
slow_mo: float = None,
9594+
headers: typing.Optional[typing.Dict[str, str]] = None
95549595
) -> "Browser":
95559596
"""BrowserType.connect
95569597
@@ -9566,6 +9607,8 @@ def connect(
95669607
slow_mo : Union[float, NoneType]
95679608
Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
95689609
Defaults to 0.
9610+
headers : Union[Dict[str, str], NoneType]
9611+
Additional HTTP headers to be sent with web socket connect request. Optional.
95699612
95709613
Returns
95719614
-------
@@ -9576,7 +9619,10 @@ def connect(
95769619
self._sync(
95779620
"browser_type.connect",
95789621
self._impl_obj.connect(
9579-
ws_endpoint=ws_endpoint, timeout=timeout, slow_mo=slow_mo
9622+
ws_endpoint=ws_endpoint,
9623+
timeout=timeout,
9624+
slow_mo=slow_mo,
9625+
headers=mapping.to_impl(headers),
95809626
),
95819627
)
95829628
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
InWheel = None
2929
from wheel.bdist_wheel import bdist_wheel as BDistWheelCommand
3030

31-
driver_version = "1.11.0-next-1619111599000"
31+
driver_version = "1.11.0-next-1619452681000"
3232

3333

3434
def extractall(zip: zipfile.ZipFile, path: str) -> None:

tests/async/test_download.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ async def test_should_error_when_saving_after_deletion(tmpdir, browser, server):
194194
await download.delete()
195195
with pytest.raises(Error) as exc:
196196
await download.save_as(user_path)
197-
assert "File already deleted. Save before deleting." in exc.value.message
197+
assert "Target page, context or browser has been closed" in exc.value.message
198198
await page.close()
199199

200200

0 commit comments

Comments
 (0)