@@ -384,6 +384,10 @@ def filter(
384384 visible = visible ,
385385 )
386386
387+ @property
388+ def visible (self ) -> "Locator" :
389+ return Locator (self ._frame , self ._selector , visible = True )
390+
387391 def or_ (self , locator : "Locator" ) -> "Locator" :
388392 if locator ._frame != self ._frame :
389393 raise Error ("Locators must belong to the same frame." )
@@ -809,13 +813,26 @@ async def hide_highlight(self) -> None:
809813 await self ._frame ._hide_highlight (self ._selector )
810814
811815
816+ ANY_FRAME_SELECTOR = "internal:control=any-frame"
817+
818+
812819class FrameLocator :
813820 def __init__ (self , frame : "Frame" , frame_selector : str ) -> None :
814821 self ._frame = frame
815822 self ._loop = frame ._loop
816823 self ._dispatcher_fiber = frame ._connection ._dispatcher_fiber
817824 self ._frame_selector = frame_selector
818825
826+ def _child_selector (self , selector : str ) -> str :
827+ if self ._frame_selector == ANY_FRAME_SELECTOR :
828+ return f"{ self ._frame_selector } >> { selector } "
829+ return f"{ self ._frame_selector } >> internal:control=enter-frame >> { selector } "
830+
831+ def _nth_selector (self , nth : str ) -> str :
832+ if self ._frame_selector == ANY_FRAME_SELECTOR :
833+ raise Error ("Selecting the nth frame is not allowed on frame_locator()." )
834+ return f"{ self ._frame_selector } >> nth={ nth } "
835+
819836 def locator (
820837 self ,
821838 selectorOrLocator : Union ["Locator" , str ],
@@ -827,7 +844,7 @@ def locator(
827844 if isinstance (selectorOrLocator , str ):
828845 return Locator (
829846 self ._frame ,
830- f" { self ._frame_selector } >> internal:control=enter-frame >> { selectorOrLocator } " ,
847+ self ._child_selector ( selectorOrLocator ) ,
831848 has_text = hasText ,
832849 has_not_text = hasNotText ,
833850 has = has ,
@@ -838,7 +855,7 @@ def locator(
838855 raise ValueError ("Locators must belong to the same frame." )
839856 return Locator (
840857 self ._frame ,
841- f" { self ._frame_selector } >> internal:control=enter-frame >> { selectorOrLocator ._selector } " ,
858+ self ._child_selector ( selectorOrLocator ._selector ) ,
842859 has_text = hasText ,
843860 has_not_text = hasNotText ,
844861 has = has ,
@@ -904,25 +921,22 @@ def get_by_title(
904921 return self .locator (get_by_title_selector (text , exact = exact ))
905922
906923 def frame_locator (self , selector : str ) -> "FrameLocator" :
907- return FrameLocator (
908- self ._frame ,
909- f"{ self ._frame_selector } >> internal:control=enter-frame >> { selector } " ,
910- )
924+ return FrameLocator (self ._frame , self ._child_selector (selector ))
911925
912926 @property
913927 def first (self ) -> "FrameLocator" :
914- return FrameLocator (self ._frame , f" { self ._frame_selector } >> nth=0" )
928+ return FrameLocator (self ._frame , self ._nth_selector ( "0" ) )
915929
916930 @property
917931 def last (self ) -> "FrameLocator" :
918- return FrameLocator (self ._frame , f" { self ._frame_selector } >> nth= -1" )
932+ return FrameLocator (self ._frame , self ._nth_selector ( " -1") )
919933
920934 @property
921935 def owner (self ) -> "Locator" :
922936 return Locator (self ._frame , self ._frame_selector )
923937
924938 def nth (self , index : int ) -> "FrameLocator" :
925- return FrameLocator (self ._frame , f" { self ._frame_selector } >> nth= { index } " )
939+ return FrameLocator (self ._frame , self ._nth_selector ( str ( index )) )
926940
927941 def __repr__ (self ) -> str :
928942 return f"<FrameLocator frame={ self ._frame !r} selector={ self ._frame_selector !r} >"
0 commit comments