นี่คือไดรเวอร์ Appium สำหรับ Safari โดยอัตโนมัติบน MacOS และ iOS ตั้งแต่เวอร์ชัน 13 ไดรเวอร์รองรับ Safari Automation โดยใช้ W3C WebDriver Protocol เท่านั้น ภายใต้ฮูดไดรเวอร์นี้เป็น wrapper/proxy ผ่านไบนารี safaridriver
ของ Apple ตรวจสอบผลลัพธ์ของคำสั่ง man safaridriver
เพื่อรับรายละเอียดเพิ่มเติมเกี่ยวกับคุณสมบัติที่รองรับและข้อผิดพลาดที่เป็นไปได้
บันทึก
เนื่องจากไดร์เวอร์เวอร์ชัน 3.0.0 Safari ได้ลดการรองรับ Appium 1 และเข้ากันได้กับ Appium 2 เท่านั้นใช้คำสั่ง
appium driver install safari
เพื่อเพิ่มลงใน Appium 2 Dist ของคุณ
จำเป็นต้องเรียกใช้คำสั่ง safaridriver --enable
เปิดใช้งานจากเทอร์มินัล MacOS และให้รหัสผ่านผู้ดูแลระบบของคุณก่อนที่จะดำเนินการเซสชันอัตโนมัติใด ๆ ในการทำให้ Safari เป็นไปโดยอัตโนมัติบนอุปกรณ์จริงจำเป็นต้องเปิดใช้งานสวิตช์อัตโนมัติระยะไกลใน Settings → Safari → Advanced → Remote Automation
สำหรับอุปกรณ์เหล่านี้
จากนั้นคุณต้องตัดสินใจว่าจะดำเนินการทดสอบอัตโนมัติที่จะดำเนินการ ไดรเวอร์ Safari รองรับแพลตฟอร์มเป้าหมายต่อไปนี้:
ไดรเวอร์ Safari อนุญาตให้กำหนดเกณฑ์หลายอย่างสำหรับการเลือกแพลตฟอร์มและปรับแต่งคุณสมบัติเซสชันอัตโนมัติของคุณ สามารถทำได้ผ่านความสามารถของเซสชันต่อไปนี้:
ชื่อความสามารถ | คำอธิบาย |
---|---|
PlatformName | Safaridriver Binary สามารถสร้างเซสชัน WebDriver สำหรับเดสก์ท็อปหรือ Safari มือถือเท่านั้นและสามารถทำงานบน MacOS เท่านั้น ค่าของ platformName อาจเท่ากับ 'MAC' หรือ 'iOS' เพื่อเริ่มต้นเซสชันไดรเวอร์ Safari สำหรับแพลตฟอร์มที่เกี่ยวข้อง ค่าของ platformName จะถูกนำมาเปรียบเทียบอย่างไม่รู้สึกตัว |
ชื่ออัตโนมัติ | ค่าของ AutomationName ต้องเท่ากับ 'Safari' เพื่อเริ่มเซสชันไดรเวอร์ Safari ค่าของระบบอัตโนมัติจะถูกนำมาเปรียบเทียบตัวพิมพ์ใหญ่ |
ชื่อเรียกดู | Safaridriver สามารถสร้างเซสชัน WebDriver สำหรับ Safari เท่านั้น ค่าใด ๆ ที่ส่งผ่านไปยังความสามารถนี้จะเปลี่ยนเป็น 'Safari' |
การสืบค้น | Safaridriver จะสร้างเซสชันโดยใช้โฮสต์ที่เวอร์ชัน Safari ตรงกับค่าของ Browserversion หมายเลขเวอร์ชันเบราว์เซอร์ถูกจับคู่คำนำหน้า ตัวอย่างเช่นหากค่าของ Browserversion คือ '12' สิ่งนี้จะอนุญาตให้โฮสต์ที่มีเวอร์ชัน Safari ของ '12 .0.1 'หรือ '12 .1' |
AcceponinsecureCerts | ทำให้เบราว์เซอร์เพิกเฉยต่อคำเตือนความปลอดภัยที่เหมาะสมและอนุญาตให้นำทางไปยังเว็บไซต์ที่มีใบรับรอง TLS ที่ไม่ถูกต้องหรือหมดอายุ ความสามารถได้รับการสนับสนุนตั้งแต่ Safaridriver v15.4 |
Safari: platformversion | Safaridriver จะสร้างเซสชันโดยใช้โฮสต์ที่เวอร์ชันระบบปฏิบัติการตรงกับค่าของ Safari: Platformversion หมายเลขเวอร์ชัน OS ถูกจับคู่คำนำหน้า ตัวอย่างเช่นหากค่าของ Safari: PlatformverSion คือ '12' สิ่งนี้จะอนุญาตให้โฮสต์ที่มีเวอร์ชัน OS ของ '12 .0 'หรือ '12 .1' แต่ไม่ใช่ '10 .12 ' |
Safari: Platformbuildversion | Safaridriver จะสร้างเซสชันโดยใช้โฮสต์ที่มีการสร้างเวอร์ชันระบบปฏิบัติการตรงกับค่าของ Safari: PlatformBuildVersion ตัวอย่างของรุ่น MacOS Build คือ '18E193' บน MacOS รุ่น Build OS สามารถกำหนดได้โดยเรียกใช้ยูทิลิตี้ SW_Vers (1) |
Safari: useimulator | หากค่าของ Safari: useimulator เป็นจริง Safaridriver จะใช้โฮสต์ iOS Simulator เท่านั้น หากค่าของ Safari: useimulator เป็นเท็จ Safaridriver จะไม่ใช้โฮสต์ iOS Simulator หมายเหตุ: จำเป็นต้องมีการติดตั้ง XCode เพื่อเรียกใช้การทดสอบ WebDriver บนโฮสต์ iOS Simulator |
Safari: DeviceType | หากค่าของ Safari: DeviceType คือ 'iPhone' Safaridriver จะสร้างเซสชันโดยใช้อุปกรณ์ iPhone หรือ iPhone จำลองเท่านั้น หากค่าของ Safari: DeviceType คือ 'iPad' Safaridriver จะสร้างเซสชันโดยใช้อุปกรณ์ iPad หรือ iPad Simulator เท่านั้น ค่าของ Safari: DeviceType ถูกนำมาเปรียบเทียบกรณีที่ไม่รู้สึก |
Safari: Devicename | Safaridriver จะสร้างเซสชันโดยใช้โฮสต์ที่ชื่ออุปกรณ์ตรงกับค่าของ Safari: Devicename ชื่ออุปกรณ์ถูกนำมาเปรียบเทียบตัวพิมพ์ใหญ่ หมายเหตุ: ชื่ออุปกรณ์สำหรับอุปกรณ์ที่เชื่อมต่อจะแสดงใน iTunes หากติดตั้ง XCode ชื่ออุปกรณ์สำหรับอุปกรณ์ที่เชื่อมต่อจะพร้อมใช้งานผ่านเอาท์พุทของเครื่องมือ (1) และในหน้าต่างอุปกรณ์และเครื่องจำลอง (เข้าถึงใน XCode ผ่าน "หน้าต่าง> อุปกรณ์และเครื่องจำลอง") |
Safari: DeviceUdid | Safaridriver จะสร้างเซสชันโดยใช้โฮสต์ที่อุปกรณ์ UDID ตรงกับค่าของ Safari: DeviceUdid อุปกรณ์ UDIDs ถูกนำมาเปรียบเทียบตัวพิมพ์ใหญ่ หมายเหตุ: หากติดตั้ง XCode UDIDs สำหรับอุปกรณ์ที่เชื่อมต่อจะพร้อมใช้งานผ่านทางเอาต์พุตของเครื่องมือ (1) และในหน้าต่างอุปกรณ์และเครื่องจำลอง (เข้าถึงใน XCode ผ่าน "หน้าต่าง> อุปกรณ์และเครื่องจำลอง") |
Safari: การตรวจสอบอัตโนมัติ | ความสามารถนี้สั่งให้ Safari โหลดผู้ตรวจการเว็บและดีบั๊ก JavaScript ในพื้นหลังก่อนที่จะกลับหน้าต่างที่สร้างขึ้นใหม่ ในการหยุดการดำเนินการทดสอบชั่วคราวใน JavaScript และนำแท็บดีบักเกอร์ของ Web Inspector คุณสามารถประเมินดีบักเกอร์ได้ คำสั่งในหน้าทดสอบ |
Safari: AutomaticProfiling | ความสามารถนี้สั่งให้ Safari โหลดผู้ตรวจการเว็บล่วงหน้าและเริ่มการบันทึกไทม์ไลน์ในพื้นหลังก่อนที่จะกลับหน้าต่างที่สร้างขึ้นใหม่ หากต้องการดูการบันทึกให้เปิดเว็บผู้ตรวจสอบผ่านเมนูพัฒนาของ Safari |
WebKit: webrtc | ความสามารถนี้ช่วยให้การทดสอบเปลี่ยนนโยบายของ Safari ชั่วคราวสำหรับ WEBRTC และการจับภาพสื่อ ค่าของ WebKit: ความสามารถของ WEBRTC เป็นพจนานุกรมที่มีคีย์ย่อยต่อไปนี้ซึ่งทั้งหมดเป็นทางเลือก: DisableInsecureMediaCapture - โดยปกติแล้ว Safari ปฏิเสธที่จะอนุญาตให้มีการจับสื่อผ่านการเชื่อมต่อที่ไม่ปลอดภัย ข้อ จำกัด นี้ผ่อนคลายโดยค่าเริ่มต้นสำหรับเซสชัน WebDriver เพื่อการทดสอบ (ตัวอย่างเช่นเว็บเซิร์ฟเวอร์ทดสอบที่ไม่ได้กำหนดค่าสำหรับ HTTPS) เมื่อมีการระบุความสามารถนี้ Safari จะกลับไปใช้พฤติกรรมปกติของการป้องกันการจับภาพสื่อผ่านการเชื่อมต่อที่ไม่ปลอดภัย DisableICECandidateFiltering - เพื่อปกป้องความเป็นส่วนตัวของผู้ใช้ Safari มักจะกรองผู้สมัคร ICE WebRTC ที่สอดคล้องกับที่อยู่เครือข่ายภายในเมื่ออุปกรณ์จับภาพไม่ได้ใช้งาน ความสามารถนี้ยับยั้งการกรองผู้สมัครน้ำแข็งเพื่อให้ที่อยู่เครือข่ายทั้งภายในและภายนอกถูกส่งเป็นผู้สมัคร 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