GeezerVison is showing github.com — feat(roll): roll Playwright 1.18.0-next-1636539685000 (#1021) · Coder-Soder/playwright-python@cd14696
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: playwright/_impl/_locator.py +20-5Lines changed: 20 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -168,7 +168,7 @@ def locator( | 168 | 168 | return Locator(self._frame, f"{self._selector} >> {selector}") | 169 | 169 |
| 170 | 170 | def frame_locator(self, selector: str) -> "FrameLocator": | 171 | | - return FrameLocator(self._frame, selector) | | 171 | + return FrameLocator(self._frame, self._selector + " >> " + selector) | 172 | 172 |
| 173 | 173 | async def element_handle( | 174 | 174 | self, | @@ -477,14 +477,29 @@ async def set_checked( | 477 | 477 |
| 478 | 478 |
| 479 | 479 | class FrameLocator: | 480 | | - def __init__(self, frame: "Frame", selector: str) -> None: | | 480 | + def __init__(self, frame: "Frame", frame_selector: str) -> None: | 481 | 481 | self._frame = frame | 482 | 482 | self._loop = frame._loop | 483 | 483 | self._dispatcher_fiber = frame._connection._dispatcher_fiber | 484 | | - self._selector = f"{selector} >> control=enter-frame" | | 484 | + self._frame_selector = frame_selector | 485 | 485 |
| 486 | 486 | def locator(self, selector: str) -> Locator: | 487 | | - return Locator(self._frame, f"{self._selector} >> {selector}") | | 487 | + return Locator( | | 488 | + self._frame, f"{self._frame_selector} >> control=enter-frame >> {selector}" | | 489 | + ) | 488 | 490 |
| 489 | 491 | def frame_locator(self, selector: str) -> "FrameLocator": | 490 | | - return FrameLocator(self._frame, f"{self._selector} >> {selector}") | | 492 | + return FrameLocator( | | 493 | + self._frame, f"{self._frame_selector} >> control=enter-frame >> {selector}" | | 494 | + ) | | 495 | + | | 496 | + @property | | 497 | + def first(self) -> "FrameLocator": | | 498 | + return FrameLocator(self._frame, f"{self._frame_selector} >> nth=0") | | 499 | + | | 500 | + @property | | 501 | + def last(self) -> "FrameLocator": | | 502 | + return FrameLocator(self._frame, f"{self._frame_selector} >> nth=-1") | | 503 | + | | 504 | + def nth(self, index: int) -> "FrameLocator": | | 505 | + return FrameLocator(self._frame, f"{self._frame_selector} >> nth={index}") |
Collapse file Copy file name to clipboardExpand all lines: playwright/async_api/_generated.py +47-7Lines changed: 47 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -5221,6 +5221,30 @@ async def set_checked( | 5221 | 5221 |
| 5222 | 5222 |
| 5223 | 5223 | class FrameLocator(AsyncBase): | | 5224 | + @property | | 5225 | + def first(self) -> "FrameLocator": | | 5226 | + """FrameLocator.first | | 5227 | + | | 5228 | + Returns locator to the first matching frame. | | 5229 | + | | 5230 | + Returns | | 5231 | + ------- | | 5232 | + FrameLocator | | 5233 | + """ | | 5234 | + return mapping.from_impl(self._impl_obj.first) | | 5235 | + | | 5236 | + @property | | 5237 | + def last(self) -> "FrameLocator": | | 5238 | + """FrameLocator.last | | 5239 | + | | 5240 | + Returns locator to the last matching frame. | | 5241 | + | | 5242 | + Returns | | 5243 | + ------- | | 5244 | + FrameLocator | | 5245 | + """ | | 5246 | + return mapping.from_impl(self._impl_obj.last) | | 5247 | + | 5224 | 5248 | def locator(self, selector: str) -> "Locator": | 5225 | 5249 | """FrameLocator.locator | 5226 | 5250 |
| @@ -5256,6 +5280,22 @@ def frame_locator(self, selector: str) -> "FrameLocator": | 5256 | 5280 |
| 5257 | 5281 | return mapping.from_impl(self._impl_obj.frame_locator(selector=selector)) | 5258 | 5282 |
| | 5283 | + def nth(self, index: int) -> "FrameLocator": | | 5284 | + """FrameLocator.nth | | 5285 | + | | 5286 | + Returns locator to the n-th matching frame. | | 5287 | + | | 5288 | + Parameters | | 5289 | + ---------- | | 5290 | + index : int | | 5291 | + | | 5292 | + Returns | | 5293 | + ------- | | 5294 | + FrameLocator | | 5295 | + """ | | 5296 | + | | 5297 | + return mapping.from_impl(self._impl_obj.nth(index=index)) | | 5298 | + | 5259 | 5299 |
| 5260 | 5300 | mapping.register(FrameLocatorImpl, FrameLocator) | 5261 | 5301 |
| @@ -13792,7 +13832,7 @@ async def delete( | 13792 | 13832 | url : str | 13793 | 13833 | Target URL. | 13794 | 13834 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13795 | | - Query parameters to be send with the URL. | | 13835 | + Query parameters to be sent with the URL. | 13796 | 13836 | headers : Union[Dict[str, str], NoneType] | 13797 | 13837 | Allows to set HTTP headers. | 13798 | 13838 | data : Union[Any, bytes, str, NoneType] | @@ -13860,7 +13900,7 @@ async def head( | 13860 | 13900 | url : str | 13861 | 13901 | Target URL. | 13862 | 13902 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13863 | | - Query parameters to be send with the URL. | | 13903 | + Query parameters to be sent with the URL. | 13864 | 13904 | headers : Union[Dict[str, str], NoneType] | 13865 | 13905 | Allows to set HTTP headers. | 13866 | 13906 | timeout : Union[float, NoneType] | @@ -13912,7 +13952,7 @@ async def get( | 13912 | 13952 | url : str | 13913 | 13953 | Target URL. | 13914 | 13954 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13915 | | - Query parameters to be send with the URL. | | 13955 | + Query parameters to be sent with the URL. | 13916 | 13956 | headers : Union[Dict[str, str], NoneType] | 13917 | 13957 | Allows to set HTTP headers. | 13918 | 13958 | timeout : Union[float, NoneType] | @@ -13969,7 +14009,7 @@ async def patch( | 13969 | 14009 | url : str | 13970 | 14010 | Target URL. | 13971 | 14011 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13972 | | - Query parameters to be send with the URL. | | 14012 | + Query parameters to be sent with the URL. | 13973 | 14013 | headers : Union[Dict[str, str], NoneType] | 13974 | 14014 | Allows to set HTTP headers. | 13975 | 14015 | data : Union[Any, bytes, str, NoneType] | @@ -14042,7 +14082,7 @@ async def put( | 14042 | 14082 | url : str | 14043 | 14083 | Target URL. | 14044 | 14084 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 14045 | | - Query parameters to be send with the URL. | | 14085 | + Query parameters to be sent with the URL. | 14046 | 14086 | headers : Union[Dict[str, str], NoneType] | 14047 | 14087 | Allows to set HTTP headers. | 14048 | 14088 | data : Union[Any, bytes, str, NoneType] | @@ -14115,7 +14155,7 @@ async def post( | 14115 | 14155 | url : str | 14116 | 14156 | Target URL. | 14117 | 14157 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 14118 | | - Query parameters to be send with the URL. | | 14158 | + Query parameters to be sent with the URL. | 14119 | 14159 | headers : Union[Dict[str, str], NoneType] | 14120 | 14160 | Allows to set HTTP headers. | 14121 | 14161 | data : Union[Any, bytes, str, NoneType] | @@ -14188,7 +14228,7 @@ async def fetch( | 14188 | 14228 | url_or_request : Union[Request, str] | 14189 | 14229 | Target URL or Request to get all parameters from. | 14190 | 14230 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 14191 | | - Query parameters to be send with the URL. | | 14231 | + Query parameters to be sent with the URL. | 14192 | 14232 | method : Union[str, NoneType] | 14193 | 14233 | If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) or | 14194 | 14234 | [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)). If not specified, GET method is used. | |
Collapse file Copy file name to clipboardExpand all lines: playwright/sync_api/_generated.py +47-7Lines changed: 47 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -5162,6 +5162,30 @@ def set_checked( | 5162 | 5162 |
| 5163 | 5163 |
| 5164 | 5164 | class FrameLocator(SyncBase): | | 5165 | + @property | | 5166 | + def first(self) -> "FrameLocator": | | 5167 | + """FrameLocator.first | | 5168 | + | | 5169 | + Returns locator to the first matching frame. | | 5170 | + | | 5171 | + Returns | | 5172 | + ------- | | 5173 | + FrameLocator | | 5174 | + """ | | 5175 | + return mapping.from_impl(self._impl_obj.first) | | 5176 | + | | 5177 | + @property | | 5178 | + def last(self) -> "FrameLocator": | | 5179 | + """FrameLocator.last | | 5180 | + | | 5181 | + Returns locator to the last matching frame. | | 5182 | + | | 5183 | + Returns | | 5184 | + ------- | | 5185 | + FrameLocator | | 5186 | + """ | | 5187 | + return mapping.from_impl(self._impl_obj.last) | | 5188 | + | 5165 | 5189 | def locator(self, selector: str) -> "Locator": | 5166 | 5190 | """FrameLocator.locator | 5167 | 5191 |
| @@ -5197,6 +5221,22 @@ def frame_locator(self, selector: str) -> "FrameLocator": | 5197 | 5221 |
| 5198 | 5222 | return mapping.from_impl(self._impl_obj.frame_locator(selector=selector)) | 5199 | 5223 |
| | 5224 | + def nth(self, index: int) -> "FrameLocator": | | 5225 | + """FrameLocator.nth | | 5226 | + | | 5227 | + Returns locator to the n-th matching frame. | | 5228 | + | | 5229 | + Parameters | | 5230 | + ---------- | | 5231 | + index : int | | 5232 | + | | 5233 | + Returns | | 5234 | + ------- | | 5235 | + FrameLocator | | 5236 | + """ | | 5237 | + | | 5238 | + return mapping.from_impl(self._impl_obj.nth(index=index)) | | 5239 | + | 5200 | 5240 |
| 5201 | 5241 | mapping.register(FrameLocatorImpl, FrameLocator) | 5202 | 5242 |
| @@ -13515,7 +13555,7 @@ def delete( | 13515 | 13555 | url : str | 13516 | 13556 | Target URL. | 13517 | 13557 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13518 | | - Query parameters to be send with the URL. | | 13558 | + Query parameters to be sent with the URL. | 13519 | 13559 | headers : Union[Dict[str, str], NoneType] | 13520 | 13560 | Allows to set HTTP headers. | 13521 | 13561 | data : Union[Any, bytes, str, NoneType] | @@ -13583,7 +13623,7 @@ def head( | 13583 | 13623 | url : str | 13584 | 13624 | Target URL. | 13585 | 13625 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13586 | | - Query parameters to be send with the URL. | | 13626 | + Query parameters to be sent with the URL. | 13587 | 13627 | headers : Union[Dict[str, str], NoneType] | 13588 | 13628 | Allows to set HTTP headers. | 13589 | 13629 | timeout : Union[float, NoneType] | @@ -13635,7 +13675,7 @@ def get( | 13635 | 13675 | url : str | 13636 | 13676 | Target URL. | 13637 | 13677 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13638 | | - Query parameters to be send with the URL. | | 13678 | + Query parameters to be sent with the URL. | 13639 | 13679 | headers : Union[Dict[str, str], NoneType] | 13640 | 13680 | Allows to set HTTP headers. | 13641 | 13681 | timeout : Union[float, NoneType] | @@ -13692,7 +13732,7 @@ def patch( | 13692 | 13732 | url : str | 13693 | 13733 | Target URL. | 13694 | 13734 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13695 | | - Query parameters to be send with the URL. | | 13735 | + Query parameters to be sent with the URL. | 13696 | 13736 | headers : Union[Dict[str, str], NoneType] | 13697 | 13737 | Allows to set HTTP headers. | 13698 | 13738 | data : Union[Any, bytes, str, NoneType] | @@ -13765,7 +13805,7 @@ def put( | 13765 | 13805 | url : str | 13766 | 13806 | Target URL. | 13767 | 13807 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13768 | | - Query parameters to be send with the URL. | | 13808 | + Query parameters to be sent with the URL. | 13769 | 13809 | headers : Union[Dict[str, str], NoneType] | 13770 | 13810 | Allows to set HTTP headers. | 13771 | 13811 | data : Union[Any, bytes, str, NoneType] | @@ -13838,7 +13878,7 @@ def post( | 13838 | 13878 | url : str | 13839 | 13879 | Target URL. | 13840 | 13880 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13841 | | - Query parameters to be send with the URL. | | 13881 | + Query parameters to be sent with the URL. | 13842 | 13882 | headers : Union[Dict[str, str], NoneType] | 13843 | 13883 | Allows to set HTTP headers. | 13844 | 13884 | data : Union[Any, bytes, str, NoneType] | @@ -13911,7 +13951,7 @@ def fetch( | 13911 | 13951 | url_or_request : Union[Request, str] | 13912 | 13952 | Target URL or Request to get all parameters from. | 13913 | 13953 | params : Union[Dict[str, Union[bool, float, str]], NoneType] | 13914 | | - Query parameters to be send with the URL. | | 13954 | + Query parameters to be sent with the URL. | 13915 | 13955 | method : Union[str, NoneType] | 13916 | 13956 | If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) or | 13917 | 13957 | [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)). If not specified, GET method is used. | |
Collapse file Copy file name to clipboardExpand all lines: setup.py +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 28 | 28 | InWheel = None | 29 | 29 | from wheel.bdist_wheel import bdist_wheel as BDistWheelCommand | 30 | 30 |
| 31 | | -driver_version = "1.17.0-next-1636463074000" | | 31 | +driver_version = "1.18.0-next-1636539685000" | 32 | 32 |
| 33 | 33 |
| 34 | 34 | def extractall(zip: zipfile.ZipFile, path: str) -> None: | |
Collapse file Copy file name to clipboardExpand all lines: tests/async/test_locators.py +48Lines changed: 48 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 13 | 13 | # limitations under the License. | 14 | 14 |
| 15 | 15 | import os | | 16 | +from urllib.parse import urlparse | 16 | 17 |
| 17 | 18 | import pytest | 18 | 19 |
| @@ -537,3 +538,50 @@ async def test_locators_frame_should_work_with_locator_frame_locator( | 537 | 538 | await button.wait_for() | 538 | 539 | assert await button.inner_text() == "Hello iframe" | 539 | 540 | await button.click() | | 541 | + | | 542 | + | | 543 | +async def route_ambiguous(page: Page) -> None: | | 544 | + await page.route( | | 545 | + "**/empty.html", | | 546 | + lambda route: route.fulfill( | | 547 | + body=""" | | 548 | + <iframe src="iframe-1.html"></iframe> | | 549 | + <iframe src="iframe-2.html"></iframe> | | 550 | + <iframe src="iframe-3.html"></iframe> | | 551 | + """, | | 552 | + content_type="text/html", | | 553 | + ), | | 554 | + ) | | 555 | + await page.route( | | 556 | + "**/iframe-*", | | 557 | + lambda route: route.fulfill( | | 558 | + body=f"<html><button>Hello from {urlparse(route.request.url).path[1:]}</button></html>", | | 559 | + content_type="text/html", | | 560 | + ), | | 561 | + ) | | 562 | + | | 563 | + | | 564 | +async def test_locator_frame_locator_should_throw_on_ambiguity( | | 565 | + page: Page, server: Server | | 566 | +) -> None: | | 567 | + await route_ambiguous(page) | | 568 | + await page.goto(server.EMPTY_PAGE) | | 569 | + button = page.locator("body").frame_locator("iframe").locator("button") | | 570 | + with pytest.raises( | | 571 | + Error, | | 572 | + match='.*strict mode violation: "body >> iframe" resolved to 3 elements.*', | | 573 | + ): | | 574 | + await button.wait_for() | | 575 | + | | 576 | + | | 577 | +async def test_locator_frame_locator_should_not_throw_on_first_last_nth( | | 578 | + page: Page, server: Server | | 579 | +) -> None: | | 580 | + await route_ambiguous(page) | | 581 | + await page.goto(server.EMPTY_PAGE) | | 582 | + button1 = page.locator("body").frame_locator("iframe").first.locator("button") | | 583 | + assert await button1.text_content() == "Hello from iframe-1.html" | | 584 | + button2 = page.locator("body").frame_locator("iframe").nth(1).locator("button") | | 585 | + assert await button2.text_content() == "Hello from iframe-2.html" | | 586 | + button3 = page.locator("body").frame_locator("iframe").last.locator("button") | | 587 | + assert await button3.text_content() == "Hello from iframe-3.html" |
|