2626 Pattern ,
2727 TypeVar ,
2828 Union ,
29+ cast ,
2930)
3031
3132from playwright ._impl ._api_structures import (
@@ -66,7 +67,13 @@ def __init__(
6667 selector : str ,
6768 has_text : Union [str , Pattern ] = None ,
6869 has : "Locator" = None ,
70+ left_of : "Locator" = None ,
71+ right_of : "Locator" = None ,
72+ above : "Locator" = None ,
73+ below : "Locator" = None ,
74+ near : "Locator" = None ,
6975 ) -> None :
76+ _params = locals ()
7077 self ._frame = frame
7178 self ._selector = selector
7279 self ._loop = frame ._loop
@@ -81,10 +88,18 @@ def __init__(
8188 escaped = escape_with_quotes (has_text , '"' )
8289 self ._selector += f" >> :scope:has-text({ escaped } )"
8390
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 )
91+ for inner in ["has" , "left_of" , "right_of" , "above" , "below" , "near" ]:
92+ locator : Optional ["Locator" ] = cast ("Locator" , _params .get (inner ))
93+ if not locator :
94+ continue
95+ if locator ._frame != frame :
96+ raise Error (f'Inner "{ inner } " locator must belong to the same frame.' )
97+ engine_name = inner
98+ if engine_name == "left_of" :
99+ engine_name = "left-of"
100+ elif engine_name == "right_of" :
101+ engine_name = "right-of"
102+ self ._selector += f" >> { engine_name } =" + json .dumps (locator ._selector )
88103
89104 def __repr__ (self ) -> str :
90105 return f"<Locator frame={ self ._frame !r} selector={ self ._selector !r} >"
@@ -200,12 +215,22 @@ def locator(
200215 selector : str ,
201216 has_text : Union [str , Pattern ] = None ,
202217 has : "Locator" = None ,
218+ left_of : "Locator" = None ,
219+ right_of : "Locator" = None ,
220+ above : "Locator" = None ,
221+ below : "Locator" = None ,
222+ near : "Locator" = None ,
203223 ) -> "Locator" :
204224 return Locator (
205225 self ._frame ,
206226 f"{ self ._selector } >> { selector } " ,
207227 has_text = has_text ,
208228 has = has ,
229+ left_of = left_of ,
230+ right_of = right_of ,
231+ above = above ,
232+ below = below ,
233+ near = near ,
209234 )
210235
211236 def frame_locator (self , selector : str ) -> "FrameLocator" :
@@ -236,16 +261,26 @@ def last(self) -> "Locator":
236261 def nth (self , index : int ) -> "Locator" :
237262 return Locator (self ._frame , f"{ self ._selector } >> nth={ index } " )
238263
239- def that (
264+ def filter (
240265 self ,
241266 has_text : Union [str , Pattern ] = None ,
242267 has : "Locator" = None ,
268+ left_of : "Locator" = None ,
269+ right_of : "Locator" = None ,
270+ above : "Locator" = None ,
271+ below : "Locator" = None ,
272+ near : "Locator" = None ,
243273 ) -> "Locator" :
244274 return Locator (
245275 self ._frame ,
246276 self ._selector ,
247277 has_text = has_text ,
248278 has = has ,
279+ left_of = left_of ,
280+ right_of = right_of ,
281+ above = above ,
282+ below = below ,
283+ near = near ,
249284 )
250285
251286 async def focus (self , timeout : float = None ) -> None :
@@ -577,13 +612,26 @@ def __init__(self, frame: "Frame", frame_selector: str) -> None:
577612 self ._frame_selector = frame_selector
578613
579614 def locator (
580- self , selector : str , has_text : Union [str , Pattern ] = None , has : "Locator" = None
615+ self ,
616+ selector : str ,
617+ has_text : Union [str , Pattern ] = None ,
618+ has : "Locator" = None ,
619+ left_of : "Locator" = None ,
620+ right_of : "Locator" = None ,
621+ above : "Locator" = None ,
622+ below : "Locator" = None ,
623+ near : "Locator" = None ,
581624 ) -> Locator :
582625 return Locator (
583626 self ._frame ,
584627 f"{ self ._frame_selector } >> control=enter-frame >> { selector } " ,
585628 has_text = has_text ,
586629 has = has ,
630+ left_of = left_of ,
631+ right_of = right_of ,
632+ above = above ,
633+ below = below ,
634+ near = near ,
587635 )
588636
589637 def frame_locator (self , selector : str ) -> "FrameLocator" :
0 commit comments