Repository: microsoft/playwright-python

Issue:
[Ports]: Backport client side changes
Please backport client side changes:
  - [x] https://github.com/microsoft/playwright/commit/82032be36838de90c169158264de32223560950b (chore(server): validate/convert protocol both ways (#14811))
  - [x] https://github.com/microsoft/playwright/commit/6cb3236acdcaac010802c12f203ae59d8e4ec4e3 (feat(chromium): Service Worker Network Instrumentation and Inspection (#14716))
  - [x] https://github.com/microsoft/playwright/commit/4eccb89a79655b4de6e7d36c4b548ecadac2b8e3 (chore: do not serialize buffers into base64 in local mode (#15316))
  - [x] https://github.com/microsoft/playwright/commit/b9e41df0a5715ded4cdbb7a9d5a7d53defe25f5c (chore: respect event name in removeAllListeners (#15430))
  - [x] https://github.com/microsoft/playwright/commit/5fc637e44aefe7a40da52d261445d32e2051b8e7 (chore: experimental resetForReuse (#15432))
  - [x] https://github.com/microsoft/playwright/commit/8402001c3265d901b92d8aea19560ca5a750de72 (chore: remove joining emitter (#15588))
  - [x] https://github.com/microsoft/playwright/commit/e4debd0bf665ae69a6621768d17e739aef13be9a (feat(matchers): add toContainClass (#15491))
  - [x] https://github.com/microsoft/playwright/commit/3939b9f36e2fa0305e431e50d94fd32364b5df36 (chore: migrate component testing to server-side page reuse (#15477))
  - [x] https://github.com/microsoft/playwright/commit/cb81d23ad69d0f4571175dfb40ba5b48d8d8de78 (fix(selectors): max hasText regex against nested nodes (#15638))
  - [x] https://github.com/microsoft/playwright/commit/4bba41ab8feb3f972aa9d27e1adfd2c8763d98e1 (Revert "feat(matchers): add toContainClass (#15491)" (#15670))
  - [x] https://github.com/microsoft/playwright/commit/a198b6d753d7710be55236ea31256c9518fb9cf5 (chore: reparent context objects into the object (#15689))


Discussion:

Resolving patch:
diff --git a/playwright/_impl/_browser_context.py b/playwright/_impl/_browser_context.py
--- a/playwright/_impl/_browser_context.py
+++ b/playwright/_impl/_browser_context.py
@@ -100,9 +100,7 @@ def __init__(
         self._service_workers: Set[Worker] = set()
         self._tracing = cast(Tracing, from_channel(initializer["tracing"]))
         self._har_recorders: Dict[str, HarRecordingMetadata] = {}
-        self._request: APIRequestContext = from_channel(
-            initializer["APIRequestContext"]
-        )
+        self._request: APIRequestContext = from_channel(initializer["requestContext"])
         self._channel.on(
             "bindingCall",
             lambda params: self._on_binding(from_channel(params["binding"])),
diff --git a/playwright/_impl/_connection.py b/playwright/_impl/_connection.py
--- a/playwright/_impl/_connection.py
+++ b/playwright/_impl/_connection.py
@@ -129,6 +129,11 @@ def _dispose(self) -> None:
             object._dispose()
         self._objects.clear()
 
+    def _adopt(self, child: "ChannelOwner") -> None:
+        del cast("ChannelOwner", child._parent)._objects[child._guid]
+        self._objects[child._guid] = child
+        child._parent = self
+
 
 class ProtocolCallback:
     def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
@@ -294,6 +299,19 @@ def dispatch(self, msg: ParsedMessagePayload) -> None:
                 parent, params["type"], params["guid"], params["initializer"]
             )
             return
+
+        object = self._objects.get(guid)
+        if not object:
+            raise Exception(f'Cannot find object to "{method}": {guid}')
+
+        if method == "__adopt__":
+            child_guid = cast(Dict[str, str], params)["guid"]
+            child = self._objects.get(child_guid)
+            if not child:
+                raise Exception(f"Unknown new child: {child_guid}")
+            object._adopt(child)
+            return
+
         if method == "__dispose__":
             self._objects[guid]._dispose()
             return
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,7 @@
     InWheel = None
 from wheel.bdist_wheel import bdist_wheel as BDistWheelCommand
 
-driver_version = "1.24.0"
+driver_version = "1.25.0-alpha-jul-26-2022"
 
 
 def extractall(zip: zipfile.ZipFile, path: str) -> None:


Test patch:
diff --git a/tests/async/test_launcher.py b/tests/async/test_launcher.py
--- a/tests/async/test_launcher.py
+++ b/tests/async/test_launcher.py
@@ -29,7 +29,10 @@ async def test_browser_type_launch_should_reject_all_promises_when_browser_is_cl
     await page.close()
     with pytest.raises(Error) as exc:
         await never_resolves
-    assert "Target closed" in exc.value.message
+    assert (
+        "Target closed" in exc.value.message
+        or "Target page, context or browser has been closed" in exc.value.message
+    )
 
 
 @pytest.mark.skip_browser("firefox")