# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you 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.
#
# modified by kaliiiiiiiiii | Aurin Aegerter
# all modifications are licensed under the license provided at LICENSE.md
import asyncio
import typing
from typing import Union
import warnings
from selenium_driverless.types.by import By
from selenium_driverless.types.alert import Alert
from selenium_driverless.types.target import TargetInfo, Target
from selenium_driverless.types.target import NoSuchIframe
from selenium_driverless.types.webelement import WebElement, NoSuchElementException
[docs]class SwitchTo:
"""
the SwitchTo class
.. warning::
except for switching to targets, do not use this class
"""
def __init__(self, context, context_id: str = None, loop: asyncio.AbstractEventLoop = None) -> None:
from selenium_driverless.types.context import Context
self._context: Context = context
self._alert = None
self._started = False
self._context_id = context_id
self._loop = loop
# noinspection PyProtectedMember
self._is_incognito = self._context._is_incognito
def __await__(self):
return self._init().__await__()
async def _init(self):
if not self._started:
self._started = True
return self
@property
async def alert(self) -> Alert:
"""Switches focus to an alert on the page.
:Usage:
::
alert = target.switch_to.alert
"""
return await self.get_alert()
[docs] async def get_alert(self, timeout: float = 5) -> Alert:
"""Switches focus to an alert on the page.
:Usage:
::
alert = target.switch_to.alert
"""
return await self._context.current_target.get_alert(timeout=timeout)
[docs] async def default_content(self, activate: bool = False) -> Target:
"""Switch focus to the default frame.
:Usage:
::
target.switch_to.default_content()
"""
base_target = self._context.current_target.base_target
if base_target:
return await self.target(target_id=base_target, activate=activate)
[docs] async def frame(self, frame_reference: Union[str, int, WebElement], focus:bool=True) -> None:
"""Switches to the specified frame
:param frame_reference: the reference by ID, name, index, or WebElement
:param focus: whether to emulate focus on the frame
:param focus: whether to emulate focus on the iframe
"""
warnings.warn(
"driver.switch_to.iframe deprecated and not reliable use Webelement.content_document instead",
DeprecationWarning)
if isinstance(frame_reference, str):
try:
frame_reference = await self._context.find_element(By.ID, frame_reference)
except NoSuchElementException:
try:
frame_reference = await self._context.find_element(By.NAME, frame_reference)
except NoSuchElementException:
pass
if isinstance(frame_reference, int):
try:
frames = await self._context.find_elements(By.TAG_NAME, "iframe")
frame_reference = frames[frame_reference]
except KeyError:
pass
if not isinstance(frame_reference, WebElement):
raise NoSuchIframe(frame_reference, f"couldn't get element by: {frame_reference}")
target = await self._context.current_target.get_target_for_iframe(frame_reference)
if focus:
await target.focus()
await self.target(target)
return target
[docs] async def target(self, target_id: typing.Union[str, TargetInfo, Target], activate: bool = False, focus:bool=True) -> Target:
"""
switches to a target
:param target_id: the target to switch to
:param activate: whether to bring the target to the front
:param focus: whether to emulate focus on the target
"""
if isinstance(target_id, TargetInfo):
self._context._current_target = target_id.Target
elif isinstance(target_id, Target):
self._context._current_target = target_id
elif isinstance(target_id, WebElement):
# noinspection PyDeprecation
self._context._current_target = self.frame(target_id)
else:
self._context._current_target = await self._context.get_target(target_id)
if activate:
await self._context.current_target.activate()
if focus:
await self._context.current_target.focus()
return self._context.current_target
[docs] async def window(self, window_id: str or TargetInfo, activate: bool = False, focus:bool=True) -> Target:
"""
switches to a window
alias to :func:`SwitchTo.target <selenium_driverless.scripts.switch_to.SwitchTo.target`
"""
return await self.target(window_id, activate=activate, focus=focus)
[docs] async def new_window(self, type_hint: typing.Literal["tab", "window"] = "tab", url="", activate: bool = False,
focus: bool = True, background: bool = True) -> Target:
"""creates a new tab or window
:param type_hint: what kind of target to create
:param url: url to start the target at
:param activate: whether to bring the target to the front
:param focus: whether to emulate focus on the target
:param background: whether to start the target in the background
"""
target = await self._context.new_window(type_hint=type_hint, url=url, activate=activate, focus=focus, background=background)
return await self.target(target)
async def parent_frame(self, activate: bool = False) -> Target:
raise NotImplemented()