Este es un controlador Appium para automatizar Safari en MacOS e iOS desde la versión 13. El controlador solo admite la automatización de Safari utilizando el protocolo W3C WebDriver. Debajo del capó, este conductor es un envoltorio/proxy sobre el binario safaridriver
de Apple. Verifique el comando de salida del man safaridriver
para obtener más detalles sobre las características compatibles y posibles dificultades.
Nota
Desde la versión 3.0.0, el controlador Safari ha eliminado el soporte de Appium 1, y solo es compatible con Appium 2. Use el comando
appium driver install safari
para agregarlo a su Dist Appium 2 DIST.
Es obligatorio ejecutar el comando safaridriver --enable
desde el terminal MACOS y proporcionar su contraseña de administrador antes de que se ejecute cualquier sesión automatizada. Para automatizar Safari en dispositivos reales, también es necesario habilitar el interruptor de automatización remoto en Settings → Safari → Advanced → Remote Automation
para estos dispositivos particulares.
Luego debe decidir dónde se ejecutará la prueba automatizada. El controlador Safari admite las siguientes plataformas de destino:
El controlador Safari permite definir múltiples criterios para la selección de plataformas y también ajustar las propiedades de su sesión de automatización. Esto podría hacerse a través de las siguientes capacidades de sesión:
Nombre de capacidad | Descripción |
---|---|
juego de plataforma | Safaridriver Binary solo puede crear sesiones de WebDriver para escritorio o safari móvil y solo puede ejecutarse en macOS. El valor de la plataforma podría igualar a 'Mac' o 'iOS' para comenzar la sesión del controlador Safari para la plataforma correspondiente. Los valores de la plataforma se comparan con caso de insensibilidad. |
nombre de automatización | El valor del nombre de automatización debe igual a 'Safari' para comenzar la sesión de controlador Safari. Los valores de AutomationName se comparan con caso de insensibilidad. |
nombre de navegación | Safaridriver solo puede crear sesiones de WebDriver para Safari. Cualquier valor pasado a esta capacidad se cambiará a 'safari'. |
navegador | Safaridriver solo creará una sesión utilizando hosts cuya versión de Safari coincide con el valor de la navegación. Los números de versión del navegador se combinan con prefijo. Por ejemplo, si el valor de la navegación es '12', esto permitirá hosts con una versión Safari de '12 .0.1 'o '12 .1'. |
AceptinSecurEcerts | Hace que el navegador ignore la advertencia de seguridad apropiada y, por lo tanto, permite la navegación a los sitios web que tienen certificados TLS inválidos o caducados. La capacidad es compatible desde Safaridriver v15.4. |
Safari: plataforma | Safaridriver solo creará una sesión utilizando hosts cuya versión del sistema operativo coincide con el valor de Safari: PlatformVersion. Los números de versión del sistema operativo están emparejados con prefijo. Por ejemplo, si el valor de Safari: PlatformVersion es '12', esto permitirá hosts con una versión del sistema operativo '12 .0 'o '12 .1' pero no '10 .12 '. |
Safari: PlatformBuildversion | Safaridriver solo creará una sesión utilizando hosts cuya versión de compilación del sistema operativo coincide con el valor de Safari: PlatformBuildVersion. El ejemplo de una versión de compilación de macOS es '18E193'. En MacOS, la versión de compilación del sistema operativo se puede determinar ejecutando la utilidad SW_VER (1). |
safari: useimulator | Si el valor de Safari: UssImulator es verdadero, SafaridRiver solo usará hosts de simulador iOS. Si el valor de Safari: useImulator es falso, SafaridRiver no utilizará hosts de simulador iOS. Nota: Se requiere una instalación de Xcode para ejecutar pruebas de WebDriver en hosts de simulador iOS. |
Safari: Tipo de deviceTet | Si el valor de Safari: DeViceType es 'iPhone', SafaridRiver solo creará una sesión usando un dispositivo iPhone o simulador de iPhone. Si el valor de Safari: DeViceType es 'iPad', SafaridRiver solo creará una sesión utilizando un dispositivo iPad o simulador de iPad. Los valores de Safari: DeViceType se comparan con caso de insensibilidad. |
Safari: nombre de device | SafaridRiver solo creará una sesión utilizando hosts cuyo nombre del dispositivo coincide con el valor de Safari: DeviceName. Los nombres de los dispositivos se comparan con caso de insensibilidad. Nota: Los nombres de los dispositivos para dispositivos conectados se muestran en iTunes. Si se instala Xcode, los nombres de dispositivos para dispositivos conectados están disponibles a través de la salida de instrumentos (1) y en la ventana de dispositivos y simuladores (accedido en Xcode a través de "Ventana> Dispositivos y simuladores"). |
Safari: DeviceUdid | SafaridRiver solo creará una sesión utilizando hosts cuyo dispositivo UDID coincide con el valor de Safari: DeviceUdid. Los UDID del dispositivo se comparan con caso de insensibilidad. Nota: Si se instala Xcode, los UDID para dispositivos conectados están disponibles a través de la salida de los instrumentos (1) y en la ventana de dispositivos y simuladores (accedido en Xcode a través de "Ventana> Dispositivos y simuladores"). |
Safari: AutomaticInspection | Esta capacidad instruye a Safari que precargue al inspector web y al depurador de JavaScript en segundo plano antes de devolver una ventana recién creada. Para pausar la ejecución de la prueba en JavaScript y presentar la pestaña del depurador del inspector web, simplemente puede evaluar un depurador; declaración en la página de prueba. |
Safari: perfilas automáticas | Esta capacidad indica que Safari precarga al Inspector Web e inicie una grabación de línea de tiempo en segundo plano antes de devolver una ventana recién creada. Para ver la grabación, abra el inspector web a través del menú Desarrollo de Safari. |
Webkit: WebRTC | Esta capacidad permite que una prueba cambie temporalmente las políticas de Safari para WebRTC y la captura de medios. El valor de la capacidad WebKit: WEBRTC es un diccionario con las siguientes subcontrates, todos los cuales son opcionales: DisableInsecureMediaCapture - Normalmente, Safari se niega a permitir la captura de medios sobre conexiones inseguras. Esta restricción está relajada de forma predeterminada para las sesiones de WebDriver para fines de prueba (por ejemplo, un servidor web de prueba no configurado para HTTPS). Cuando se especifica esta capacidad, Safari volverá al comportamiento normal de prevenir la captura de los medios sobre conexiones inseguras. DisableICECandidateFiltering : para proteger la privacidad de un usuario, Safari normalmente filtra a los candidatos de ICE WEBRTC que corresponden a direcciones de red internas cuando los dispositivos de captura no están en uso. Esta capacidad suprime el filtrado de los candidatos de hielo para que las direcciones de red interna y externa siempre se envíen como candidatos a ICE. |
# Python3 + PyTest
import pytest
import time
from appium import webdriver
# Options are available in Python client since v2.6.0
from appium . options . ios import SafariOptions
from selenium . webdriver . common . by import By
def generate_options ():
common_caps = {
# It does not really matter what to put there, although setting 'Safari' might cause a failure
# depending on the particular client library
'browserName' : 'AppiumSafari' ,
}
real_device_opts = SafariOptions (). load_capabilities ( common_caps )
# This is optional
real_device_opts . device_type = 'iPhone'
# Do not forget to verify that Remote Automation is enabled for this device
real_device_opts . device_udid = '<MyDeviceUDID>'
real_device_opts . use_simulator = False
simulator_opts = SafariOptions (). load_capabilities ( common_caps )
simulator_opts . platform_version = '14.1'
simulator_opts . device_name = 'iPad Air 2'
simulator_opts . use_simulator = True
desktop_browser_opts = SafariOptions (). load_capabilities ({
** common_caps ,
'platformName' : 'Mac' ,
})
return [ real_device_opts , simulator_opts , desktop_browser_opts ]
@ pytest . fixture ( params = generate_options ())
def driver ( request ):
# The default URL is http://127.0.0.1:4723/wd/hub in Appium1
drv = webdriver . Remote ( 'http://127.0.0.1:4723' , options = request . param )
yield drv
drv . quit ()
class TimeoutError ( Exception ):
pass
def wait_until_truthy ( func , timeout_sec = 5.0 , interval_sec = 0.5 ):
started = time . time ()
original_error = None
while time . time () - started < timeout_sec :
original_error = None
try :
result = func ()
if result :
return result
except Exception as e :
original_error = e
time . sleep ( interval_sec )
if original_error is None :
raise TimeoutError ( f'Condition unmet after { timeout_sec } s timeout' )
raise original_error
def test_feature_status_page_search ( driver ):
driver . get ( 'https://webkit.org/status/' )
# Enter "CSS" into the search box.
# Ensures that at least one result appears in search
# !!! Remember there are no ID and NAME locators in W3C standard
# These two have been superseded by CSS ones
search_box = driver . find_element_by_css ( '#search' )
search_box . send_keys ( 'CSS' )
value = search_box . get_attribute ( 'value' )
assert len ( value ) > 0
search_box . submit ()
# Count the visible results when filters are applied
# so one result shows up in at most one filter
assert wait_until_truthy ( lambda : len ( driver . execute_script ( "return document.querySelectorAll('li.feature:not(.is-hidden)')" )) > 0 )
def test_feature_status_page_filters ( driver ):
driver . get ( 'https://webkit.org/status/' )
assert wait_until_truthy ( lambda : len ( driver . execute_script ( "return document.querySelectorAll('.filter-toggle')" )) == 7 )
# Make sure every filter is turned off.
for checked_filter in filter ( lambda f : f . is_selected (), filters ):
checked_filter . click ()
# Make sure you can select every filter.
for filt in filters :
filt . click ()
assert filt . is_selected ()
filt . click ()
# clone repo, then in repo dir:
npm install
npm run lint
npm run test