DebanjanB: Вам известна какая-то документация / книга, в которой подробно объясняются все HTML DOM, Framesets, загрузка кадров, взаимодействие с javascript, вызовы AJAX и т. Д. И т. Д. И т. Д.?
я довольно сложная настройка веб-страницы, которую мне нужно протестировать, она содержит вложенные фреймы.
В реальной задаче код селена загружает новое содержимое веб-страницы, содержащее фрейм, на который я хочу перейти. Чтобы избежать явных ожиданий, я попробовал следующий фрагмент кода:
self.driver.switch_to_default_content()
WebDriverWait(self.driver, 300).\
until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame1')))
WebDriverWait(self.driver, 300).\
until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame2')))
Тем не менее этот фрагмент всегда терпит неудачу и приводит к следующей ошибке:
...
File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 71, in until
value = method(self._driver)
File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/expected_conditions.py", line 247, in __call__
self.frame_locator))
File "/home/adietz/Projects/Venv/nosetests/local/lib/python2.7/site-packages/selenium/webdriver/support/expected_conditions.py", line 402, in _find_element
raise e
WebDriverException: Message: TypeError: can't access dead object
Однако, если я использую сон в дополнение:
time.sleep(30)
self.driver.switch_to_default_content()
WebDriverWait(self.driver, 300).\
until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame1')))
WebDriverWait(self.driver, 300).\
until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'frame2')))
Селен способен найти кадр внутри кадра и переключиться на него. Похоже, что в случае ошибки селен переключается на «frame1», в то время как «frame2» еще не загружен, но «frame2» загружается в каком-то другом экземпляре «frame1» или не распознается селеном (может быть, ошибкой?). Так что теперь селен находится внутри некоторого «frame1» и по некоторым причинам не понимает, что «frame2» был загружен.
Единственный способ, которым я могу это исправить (без долгого сна), это использовать этот уродливый кусок кода:
mustend = time.time() + 300
while time.time() < mustend:
try:
self.driver.switch_to_default_content()
self.driver.switch_to.frame(self.driver.find_element_by_id("frame1"))
self.driver.switch_to.frame(self.driver.find_element_by_id("frame2"))
break
except WebDriverException as e:
self.log("Sleeping 1 sec")
time.sleep(1)
if time.time() > mustend:
raise TimeoutException
Поэтому всякий раз, когда я получаюWebDriverException
(мертвый объект), я иду к кадру верхнего уровня и пытаюсь переключиться на внутренний кадр - кадр за кадром.
Есть ли другой подход, который я могу попробовать?
Дополнительная информация
Фреймы вложены, то есть frame2 находится внутри frame1.