| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952 |
- # Copyright (c) Microsoft Corporation.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import json
- import pathlib
- import re
- from typing import (
- TYPE_CHECKING,
- Any,
- Awaitable,
- Callable,
- Dict,
- List,
- Literal,
- Optional,
- Pattern,
- Sequence,
- Tuple,
- TypeVar,
- Union,
- )
- from playwright._impl._api_structures import (
- AriaRole,
- FilePayload,
- FloatRect,
- FrameExpectOptions,
- FrameExpectResult,
- Position,
- )
- from playwright._impl._element_handle import ElementHandle
- from playwright._impl._helper import (
- Error,
- KeyboardModifier,
- MouseButton,
- locals_to_params,
- monotonic_time,
- to_impl,
- )
- from playwright._impl._js_handle import Serializable
- from playwright._impl._str_utils import (
- escape_for_attribute_selector,
- escape_for_text_selector,
- )
- if TYPE_CHECKING: # pragma: no cover
- from playwright._impl._frame import Frame
- from playwright._impl._js_handle import JSHandle
- from playwright._impl._page import Page
- T = TypeVar("T")
- class Locator:
- def __init__(
- self,
- frame: "Frame",
- selector: str,
- has_text: Union[str, Pattern[str]] = None,
- has_not_text: Union[str, Pattern[str]] = None,
- has: "Locator" = None,
- has_not: "Locator" = None,
- visible: bool = None,
- ) -> None:
- self._frame = frame
- self._selector = selector
- self._loop = frame._loop
- self._dispatcher_fiber = frame._connection._dispatcher_fiber
- if has_text:
- self._selector += f" >> internal:has-text={escape_for_text_selector(has_text, exact=False)}"
- if has:
- if has._frame != frame:
- raise Error('Inner "has" locator must belong to the same frame.')
- self._selector += " >> internal:has=" + json.dumps(
- has._selector, ensure_ascii=False
- )
- if has_not_text:
- self._selector += f" >> internal:has-not-text={escape_for_text_selector(has_not_text, exact=False)}"
- if has_not:
- locator = has_not
- if locator._frame != frame:
- raise Error('Inner "has_not" locator must belong to the same frame.')
- self._selector += " >> internal:has-not=" + json.dumps(locator._selector)
- if visible is not None:
- self._selector += f" >> visible={bool_to_js_bool(visible)}"
- def __repr__(self) -> str:
- return f"<Locator frame={self._frame!r} selector={self._selector!r}>"
- async def _with_element(
- self,
- task: Callable[[ElementHandle, float], Awaitable[T]],
- timeout: float = None,
- ) -> T:
- timeout = self._frame._timeout(timeout)
- deadline = (monotonic_time() + timeout) if timeout else 0
- handle = await self.element_handle(timeout=timeout)
- if not handle:
- raise Error(f"Could not resolve {self._selector} to DOM Element")
- try:
- return await task(
- handle,
- (deadline - monotonic_time()) if deadline else 0,
- )
- finally:
- await handle.dispose()
- def _equals(self, locator: "Locator") -> bool:
- return self._frame == locator._frame and self._selector == locator._selector
- @property
- def page(self) -> "Page":
- return self._frame.page
- async def bounding_box(self, timeout: float = None) -> Optional[FloatRect]:
- return await self._with_element(
- lambda h, _: h.bounding_box(),
- timeout,
- )
- async def check(
- self,
- position: Position = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.check(self._selector, strict=True, **params)
- async def click(
- self,
- modifiers: Sequence[KeyboardModifier] = None,
- position: Position = None,
- delay: float = None,
- button: MouseButton = None,
- clickCount: int = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- steps: int = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame._click(self._selector, strict=True, **params)
- async def dblclick(
- self,
- modifiers: Sequence[KeyboardModifier] = None,
- position: Position = None,
- delay: float = None,
- button: MouseButton = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- steps: int = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.dblclick(self._selector, strict=True, **params)
- async def dispatch_event(
- self,
- type: str,
- eventInit: Dict = None,
- timeout: float = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.dispatch_event(self._selector, strict=True, **params)
- async def evaluate(
- self, expression: str, arg: Serializable = None, timeout: float = None
- ) -> Any:
- return await self._with_element(
- lambda h, _: h.evaluate(expression, arg),
- timeout,
- )
- async def evaluate_all(self, expression: str, arg: Serializable = None) -> Any:
- params = locals_to_params(locals())
- return await self._frame.eval_on_selector_all(self._selector, **params)
- async def evaluate_handle(
- self, expression: str, arg: Serializable = None, timeout: float = None
- ) -> "JSHandle":
- return await self._with_element(
- lambda h, _: h.evaluate_handle(expression, arg), timeout
- )
- async def fill(
- self,
- value: str,
- timeout: float = None,
- noWaitAfter: bool = None,
- force: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.fill(self._selector, strict=True, **params)
- async def clear(
- self,
- timeout: float = None,
- noWaitAfter: bool = None,
- force: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- await self._frame._fill(self._selector, value="", title="Clear", **params)
- def locator(
- self,
- selectorOrLocator: Union[str, "Locator"],
- hasText: Union[str, Pattern[str]] = None,
- hasNotText: Union[str, Pattern[str]] = None,
- has: "Locator" = None,
- hasNot: "Locator" = None,
- ) -> "Locator":
- if isinstance(selectorOrLocator, str):
- return Locator(
- self._frame,
- f"{self._selector} >> {selectorOrLocator}",
- has_text=hasText,
- has_not_text=hasNotText,
- has_not=hasNot,
- has=has,
- )
- selectorOrLocator = to_impl(selectorOrLocator)
- if selectorOrLocator._frame != self._frame:
- raise Error("Locators must belong to the same frame.")
- return Locator(
- self._frame,
- f"{self._selector} >> internal:chain={json.dumps(selectorOrLocator._selector)}",
- has_text=hasText,
- has_not_text=hasNotText,
- has_not=hasNot,
- has=has,
- )
- def get_by_alt_text(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_alt_text_selector(text, exact=exact))
- def get_by_label(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_label_selector(text, exact=exact))
- def get_by_placeholder(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_placeholder_selector(text, exact=exact))
- def get_by_role(
- self,
- role: AriaRole,
- checked: bool = None,
- disabled: bool = None,
- expanded: bool = None,
- includeHidden: bool = None,
- level: int = None,
- name: Union[str, Pattern[str]] = None,
- pressed: bool = None,
- selected: bool = None,
- exact: bool = None,
- ) -> "Locator":
- return self.locator(
- get_by_role_selector(
- role,
- checked=checked,
- disabled=disabled,
- expanded=expanded,
- includeHidden=includeHidden,
- level=level,
- name=name,
- pressed=pressed,
- selected=selected,
- exact=exact,
- )
- )
- def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
- return self.locator(get_by_test_id_selector(test_id_attribute_name(), testId))
- def get_by_text(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_text_selector(text, exact=exact))
- def get_by_title(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_title_selector(text, exact=exact))
- def frame_locator(self, selector: str) -> "FrameLocator":
- return FrameLocator(self._frame, self._selector + " >> " + selector)
- async def element_handle(
- self,
- timeout: float = None,
- ) -> ElementHandle:
- params = locals_to_params(locals())
- handle = await self._frame.wait_for_selector(
- self._selector, strict=True, state="attached", **params
- )
- assert handle
- return handle
- async def element_handles(self) -> List[ElementHandle]:
- return await self._frame.query_selector_all(self._selector)
- @property
- def first(self) -> "Locator":
- return Locator(self._frame, f"{self._selector} >> nth=0")
- @property
- def last(self) -> "Locator":
- return Locator(self._frame, f"{self._selector} >> nth=-1")
- def nth(self, index: int) -> "Locator":
- return Locator(self._frame, f"{self._selector} >> nth={index}")
- @property
- def content_frame(self) -> "FrameLocator":
- return FrameLocator(self._frame, self._selector)
- def describe(self, description: str) -> "Locator":
- return Locator(
- self._frame,
- f"{self._selector} >> internal:describe={json.dumps(description)}",
- )
- @property
- def description(self) -> Optional[str]:
- try:
- match = re.search(
- r' >> internal:describe=("(?:[^"\\]|\\.)*")$', self._selector
- )
- if match:
- description = json.loads(match.group(1))
- if isinstance(description, str):
- return description
- except (json.JSONDecodeError, ValueError):
- pass
- return None
- def filter(
- self,
- hasText: Union[str, Pattern[str]] = None,
- hasNotText: Union[str, Pattern[str]] = None,
- has: "Locator" = None,
- hasNot: "Locator" = None,
- visible: bool = None,
- ) -> "Locator":
- return Locator(
- self._frame,
- self._selector,
- has_text=hasText,
- has_not_text=hasNotText,
- has=has,
- has_not=hasNot,
- visible=visible,
- )
- def or_(self, locator: "Locator") -> "Locator":
- if locator._frame != self._frame:
- raise Error("Locators must belong to the same frame.")
- return Locator(
- self._frame,
- self._selector + " >> internal:or=" + json.dumps(locator._selector),
- )
- def and_(self, locator: "Locator") -> "Locator":
- if locator._frame != self._frame:
- raise Error("Locators must belong to the same frame.")
- return Locator(
- self._frame,
- self._selector + " >> internal:and=" + json.dumps(locator._selector),
- )
- async def focus(self, timeout: float = None) -> None:
- params = locals_to_params(locals())
- return await self._frame.focus(self._selector, strict=True, **params)
- async def blur(self, timeout: float = None) -> None:
- await self._frame._channel.send(
- "blur",
- self._frame._timeout,
- {
- "selector": self._selector,
- "strict": True,
- **locals_to_params(locals()),
- },
- )
- async def all(
- self,
- ) -> List["Locator"]:
- result = []
- for index in range(await self.count()):
- result.append(self.nth(index))
- return result
- async def count(
- self,
- ) -> int:
- return await self._frame._query_count(self._selector)
- async def drag_to(
- self,
- target: "Locator",
- force: bool = None,
- noWaitAfter: bool = None,
- timeout: float = None,
- trial: bool = None,
- sourcePosition: Position = None,
- targetPosition: Position = None,
- steps: int = None,
- ) -> None:
- params = locals_to_params(locals())
- del params["target"]
- return await self._frame.drag_and_drop(
- self._selector, target._selector, strict=True, **params
- )
- async def get_attribute(self, name: str, timeout: float = None) -> Optional[str]:
- params = locals_to_params(locals())
- return await self._frame.get_attribute(
- self._selector,
- strict=True,
- **params,
- )
- async def hover(
- self,
- modifiers: Sequence[KeyboardModifier] = None,
- position: Position = None,
- timeout: float = None,
- noWaitAfter: bool = None,
- force: bool = None,
- trial: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.hover(
- self._selector,
- strict=True,
- **params,
- )
- async def inner_html(self, timeout: float = None) -> str:
- params = locals_to_params(locals())
- return await self._frame.inner_html(
- self._selector,
- strict=True,
- **params,
- )
- async def inner_text(self, timeout: float = None) -> str:
- params = locals_to_params(locals())
- return await self._frame.inner_text(
- self._selector,
- strict=True,
- **params,
- )
- async def input_value(self, timeout: float = None) -> str:
- params = locals_to_params(locals())
- return await self._frame.input_value(
- self._selector,
- strict=True,
- **params,
- )
- async def is_checked(self, timeout: float = None) -> bool:
- params = locals_to_params(locals())
- return await self._frame.is_checked(
- self._selector,
- strict=True,
- **params,
- )
- async def is_disabled(self, timeout: float = None) -> bool:
- params = locals_to_params(locals())
- return await self._frame.is_disabled(
- self._selector,
- strict=True,
- **params,
- )
- async def is_editable(self, timeout: float = None) -> bool:
- params = locals_to_params(locals())
- return await self._frame.is_editable(
- self._selector,
- strict=True,
- **params,
- )
- async def is_enabled(self, timeout: float = None) -> bool:
- params = locals_to_params(locals())
- return await self._frame.is_enabled(
- self._selector,
- strict=True,
- **params,
- )
- async def is_hidden(self, timeout: float = None) -> bool:
- # timeout is deprecated and does nothing
- return await self._frame.is_hidden(
- self._selector,
- strict=True,
- )
- async def is_visible(self, timeout: float = None) -> bool:
- # timeout is deprecated and does nothing
- return await self._frame.is_visible(
- self._selector,
- strict=True,
- )
- async def press(
- self,
- key: str,
- delay: float = None,
- timeout: float = None,
- noWaitAfter: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.press(self._selector, strict=True, **params)
- async def screenshot(
- self,
- timeout: float = None,
- type: Literal["jpeg", "png"] = None,
- path: Union[str, pathlib.Path] = None,
- quality: int = None,
- omitBackground: bool = None,
- animations: Literal["allow", "disabled"] = None,
- caret: Literal["hide", "initial"] = None,
- scale: Literal["css", "device"] = None,
- mask: Sequence["Locator"] = None,
- maskColor: str = None,
- style: str = None,
- ) -> bytes:
- params = locals_to_params(locals())
- return await self._with_element(
- lambda h, timeout: h.screenshot(
- **{**params, "timeout": timeout},
- ),
- )
- async def aria_snapshot(self, timeout: float = None) -> str:
- return await self._frame._channel.send(
- "ariaSnapshot",
- self._frame._timeout,
- {
- "selector": self._selector,
- **locals_to_params(locals()),
- },
- )
- async def scroll_into_view_if_needed(
- self,
- timeout: float = None,
- ) -> None:
- return await self._with_element(
- lambda h, timeout: h.scroll_into_view_if_needed(timeout=timeout),
- timeout,
- )
- async def select_option(
- self,
- value: Union[str, Sequence[str]] = None,
- index: Union[int, Sequence[int]] = None,
- label: Union[str, Sequence[str]] = None,
- element: Union["ElementHandle", Sequence["ElementHandle"]] = None,
- timeout: float = None,
- noWaitAfter: bool = None,
- force: bool = None,
- ) -> List[str]:
- params = locals_to_params(locals())
- return await self._frame.select_option(
- self._selector,
- strict=True,
- **params,
- )
- async def select_text(self, force: bool = None, timeout: float = None) -> None:
- params = locals_to_params(locals())
- return await self._with_element(
- lambda h, timeout: h.select_text(**{**params, "timeout": timeout}),
- timeout,
- )
- async def set_input_files(
- self,
- files: Union[
- str,
- pathlib.Path,
- FilePayload,
- Sequence[Union[str, pathlib.Path]],
- Sequence[FilePayload],
- ],
- timeout: float = None,
- noWaitAfter: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.set_input_files(
- self._selector,
- strict=True,
- **params,
- )
- async def tap(
- self,
- modifiers: Sequence[KeyboardModifier] = None,
- position: Position = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.tap(
- self._selector,
- strict=True,
- **params,
- )
- async def text_content(self, timeout: float = None) -> Optional[str]:
- params = locals_to_params(locals())
- return await self._frame.text_content(
- self._selector,
- strict=True,
- **params,
- )
- async def type(
- self,
- text: str,
- delay: float = None,
- timeout: float = None,
- noWaitAfter: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.type(
- self._selector,
- strict=True,
- **params,
- )
- async def press_sequentially(
- self,
- text: str,
- delay: float = None,
- timeout: float = None,
- noWaitAfter: bool = None,
- ) -> None:
- await self.type(text, delay=delay, timeout=timeout)
- async def uncheck(
- self,
- position: Position = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- ) -> None:
- params = locals_to_params(locals())
- return await self._frame.uncheck(
- self._selector,
- strict=True,
- **params,
- )
- async def all_inner_texts(
- self,
- ) -> List[str]:
- return await self._frame.eval_on_selector_all(
- self._selector, "ee => ee.map(e => e.innerText)"
- )
- async def all_text_contents(
- self,
- ) -> List[str]:
- return await self._frame.eval_on_selector_all(
- self._selector, "ee => ee.map(e => e.textContent || '')"
- )
- async def wait_for(
- self,
- timeout: float = None,
- state: Literal["attached", "detached", "hidden", "visible"] = None,
- ) -> None:
- await self._frame.wait_for_selector(
- self._selector, strict=True, timeout=timeout, state=state
- )
- async def set_checked(
- self,
- checked: bool,
- position: Position = None,
- timeout: float = None,
- force: bool = None,
- noWaitAfter: bool = None,
- trial: bool = None,
- ) -> None:
- if checked:
- await self.check(
- position=position,
- timeout=timeout,
- force=force,
- trial=trial,
- )
- else:
- await self.uncheck(
- position=position,
- timeout=timeout,
- force=force,
- trial=trial,
- )
- async def _expect(
- self,
- expression: str,
- options: FrameExpectOptions,
- title: str = None,
- ) -> FrameExpectResult:
- return await self._frame._expect(self._selector, expression, options, title)
- async def highlight(self) -> None:
- await self._frame._highlight(self._selector)
- class FrameLocator:
- def __init__(self, frame: "Frame", frame_selector: str) -> None:
- self._frame = frame
- self._loop = frame._loop
- self._dispatcher_fiber = frame._connection._dispatcher_fiber
- self._frame_selector = frame_selector
- def locator(
- self,
- selectorOrLocator: Union["Locator", str],
- hasText: Union[str, Pattern[str]] = None,
- hasNotText: Union[str, Pattern[str]] = None,
- has: Locator = None,
- hasNot: Locator = None,
- ) -> Locator:
- if isinstance(selectorOrLocator, str):
- return Locator(
- self._frame,
- f"{self._frame_selector} >> internal:control=enter-frame >> {selectorOrLocator}",
- has_text=hasText,
- has_not_text=hasNotText,
- has=has,
- has_not=hasNot,
- )
- selectorOrLocator = to_impl(selectorOrLocator)
- if selectorOrLocator._frame != self._frame:
- raise ValueError("Locators must belong to the same frame.")
- return Locator(
- self._frame,
- f"{self._frame_selector} >> internal:control=enter-frame >> {selectorOrLocator._selector}",
- has_text=hasText,
- has_not_text=hasNotText,
- has=has,
- has_not=hasNot,
- )
- def get_by_alt_text(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_alt_text_selector(text, exact=exact))
- def get_by_label(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_label_selector(text, exact=exact))
- def get_by_placeholder(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_placeholder_selector(text, exact=exact))
- def get_by_role(
- self,
- role: AriaRole,
- checked: bool = None,
- disabled: bool = None,
- expanded: bool = None,
- includeHidden: bool = None,
- level: int = None,
- name: Union[str, Pattern[str]] = None,
- pressed: bool = None,
- selected: bool = None,
- exact: bool = None,
- ) -> "Locator":
- return self.locator(
- get_by_role_selector(
- role,
- checked=checked,
- disabled=disabled,
- expanded=expanded,
- includeHidden=includeHidden,
- level=level,
- name=name,
- pressed=pressed,
- selected=selected,
- exact=exact,
- )
- )
- def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
- return self.locator(get_by_test_id_selector(test_id_attribute_name(), testId))
- def get_by_text(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_text_selector(text, exact=exact))
- def get_by_title(
- self, text: Union[str, Pattern[str]], exact: bool = None
- ) -> "Locator":
- return self.locator(get_by_title_selector(text, exact=exact))
- def frame_locator(self, selector: str) -> "FrameLocator":
- return FrameLocator(
- self._frame,
- f"{self._frame_selector} >> internal:control=enter-frame >> {selector}",
- )
- @property
- def first(self) -> "FrameLocator":
- return FrameLocator(self._frame, f"{self._frame_selector} >> nth=0")
- @property
- def last(self) -> "FrameLocator":
- return FrameLocator(self._frame, f"{self._frame_selector} >> nth=-1")
- @property
- def owner(self) -> "Locator":
- return Locator(self._frame, self._frame_selector)
- def nth(self, index: int) -> "FrameLocator":
- return FrameLocator(self._frame, f"{self._frame_selector} >> nth={index}")
- def __repr__(self) -> str:
- return f"<FrameLocator frame={self._frame!r} selector={self._frame_selector!r}>"
- _test_id_attribute_name: str = "data-testid"
- def test_id_attribute_name() -> str:
- return _test_id_attribute_name
- def set_test_id_attribute_name(attribute_name: str) -> None:
- global _test_id_attribute_name
- _test_id_attribute_name = attribute_name
- def get_by_test_id_selector(
- test_id_attribute_name: str, test_id: Union[str, Pattern[str]]
- ) -> str:
- return f"internal:testid=[{test_id_attribute_name}={escape_for_attribute_selector(test_id, True)}]"
- def get_by_attribute_text_selector(
- attr_name: str, text: Union[str, Pattern[str]], exact: bool = None
- ) -> str:
- return f"internal:attr=[{attr_name}={escape_for_attribute_selector(text, exact=exact)}]"
- def get_by_label_selector(text: Union[str, Pattern[str]], exact: bool = None) -> str:
- return "internal:label=" + escape_for_text_selector(text, exact=exact)
- def get_by_alt_text_selector(text: Union[str, Pattern[str]], exact: bool = None) -> str:
- return get_by_attribute_text_selector("alt", text, exact=exact)
- def get_by_title_selector(text: Union[str, Pattern[str]], exact: bool = None) -> str:
- return get_by_attribute_text_selector("title", text, exact=exact)
- def get_by_placeholder_selector(
- text: Union[str, Pattern[str]], exact: bool = None
- ) -> str:
- return get_by_attribute_text_selector("placeholder", text, exact=exact)
- def get_by_text_selector(text: Union[str, Pattern[str]], exact: bool = None) -> str:
- return "internal:text=" + escape_for_text_selector(text, exact=exact)
- def bool_to_js_bool(value: bool) -> str:
- return "true" if value else "false"
- def get_by_role_selector(
- role: AriaRole,
- checked: bool = None,
- disabled: bool = None,
- expanded: bool = None,
- includeHidden: bool = None,
- level: int = None,
- name: Union[str, Pattern[str]] = None,
- pressed: bool = None,
- selected: bool = None,
- exact: bool = None,
- ) -> str:
- props: List[Tuple[str, str]] = []
- if checked is not None:
- props.append(("checked", bool_to_js_bool(checked)))
- if disabled is not None:
- props.append(("disabled", bool_to_js_bool(disabled)))
- if selected is not None:
- props.append(("selected", bool_to_js_bool(selected)))
- if expanded is not None:
- props.append(("expanded", bool_to_js_bool(expanded)))
- if includeHidden is not None:
- props.append(("include-hidden", bool_to_js_bool(includeHidden)))
- if level is not None:
- props.append(("level", str(level)))
- if name is not None:
- props.append(
- (
- "name",
- escape_for_attribute_selector(name, exact=exact),
- )
- )
- if pressed is not None:
- props.append(("pressed", bool_to_js_bool(pressed)))
- props_str = "".join([f"[{t[0]}={t[1]}]" for t in props])
- return f"internal:role={role}{props_str}"
|