12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
+ import json
15
16
import pathlib
16
17
import sys
17
18
from typing import (
53
54
if TYPE_CHECKING : # pragma: no cover
54
55
from playwright ._impl ._frame import Frame
55
56
from playwright ._impl ._js_handle import JSHandle
57
+ from playwright ._impl ._page import Page
56
58
57
59
T = TypeVar ("T" )
58
60
59
61
60
62
class Locator :
61
63
def __init__ (
62
- self , frame : "Frame" , selector : str , has_text : Union [str , Pattern ] = None
64
+ self ,
65
+ frame : "Frame" ,
66
+ selector : str ,
67
+ has_text : Union [str , Pattern ] = None ,
68
+ has : "Locator" = None ,
63
69
) -> None :
64
70
self ._frame = frame
65
71
self ._selector = selector
@@ -75,6 +81,11 @@ def __init__(
75
81
escaped = escape_with_quotes (has_text , '"' )
76
82
self ._selector += f" >> :scope:has-text({ escaped } )"
77
83
84
+ if has :
85
+ if has ._frame != frame :
86
+ raise Error ('Inner "has" locator must belong to the same frame.' )
87
+ self ._selector += " >> has=" + json .dumps (has ._selector )
88
+
78
89
def __repr__ (self ) -> str :
79
90
return f"<Locator frame={ self ._frame !r} selector={ self ._selector !r} >"
80
91
@@ -96,6 +107,10 @@ async def _with_element(
96
107
finally :
97
108
await handle .dispose ()
98
109
110
+ @property
111
+ def page (self ) -> "Page" :
112
+ return self ._frame .page
113
+
99
114
async def bounding_box (self , timeout : float = None ) -> Optional [FloatRect ]:
100
115
return await self ._with_element (
101
116
lambda h , _ : h .bounding_box (),
@@ -184,9 +199,13 @@ def locator(
184
199
self ,
185
200
selector : str ,
186
201
has_text : Union [str , Pattern ] = None ,
202
+ has : "Locator" = None ,
187
203
) -> "Locator" :
188
204
return Locator (
189
- self ._frame , f"{ self ._selector } >> { selector } " , has_text = has_text
205
+ self ._frame ,
206
+ f"{ self ._selector } >> { selector } " ,
207
+ has_text = has_text ,
208
+ has = has ,
190
209
)
191
210
192
211
def frame_locator (self , selector : str ) -> "FrameLocator" :
@@ -538,11 +557,14 @@ def __init__(self, frame: "Frame", frame_selector: str) -> None:
538
557
self ._dispatcher_fiber = frame ._connection ._dispatcher_fiber
539
558
self ._frame_selector = frame_selector
540
559
541
- def locator (self , selector : str , has_text : Union [str , Pattern ] = None ) -> Locator :
560
+ def locator (
561
+ self , selector : str , has_text : Union [str , Pattern ] = None , has : "Locator" = None
562
+ ) -> Locator :
542
563
return Locator (
543
564
self ._frame ,
544
565
f"{ self ._frame_selector } >> control=enter-frame >> { selector } " ,
545
566
has_text = has_text ,
567
+ has = has ,
546
568
)
547
569
548
570
def frame_locator (self , selector : str ) -> "FrameLocator" :
0 commit comments