Python Selenium WebDriver。 写我自己的预期条件
我试图写我自己的预期条件。 我需要什么…我有一个iframe。 而且我也有一个形象。 当图像的scr会改变时,我想继续处理。 我做了什么:
class url_changed_condition(object): ''' Checks whether url in iframe has changed or not ''' def __init__(self, urls): self._current_url, self._new_url = urls def __call__(self, ignored): return self._current_url != self._new_url
后来在代码中我有:
def process_image(self, locator, current_url): try: WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.TAG_NAME, u"iframe"))) iframe = self.driver.find_element(*locator) if iframe: print "Iframe found!" self.driver.switch_to_frame(iframe) WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.XPATH, u"//div"))) # WebDriverWait(self.driver, 10).until( # url_changed_condition( # (current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src")))) img_url = self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src") print img_url self.search_dict[self._search_item].append(img_url) self.driver.switch_to_default_content() except NoSuchElementException as NSE: print "iframe not found! {0}".format(NSE.msg) except: print "something went wrong" import traceback import sys type_, value_, trace_ = sys.exc_info() print type_, value_ print traceback.format_tb(trace_) finally: return current_url
此代码可以工作,但会多次返回相同的url。 问题是当我取消注释url_changed_condition
它落在TimeoutException
中
(current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))
下面的线路正常工作…我不明白。
看起来像这个主题没有一个自定义预期条件的例子。
这其实很简单。 首先, Python selenium绑定中的预期条件是什么:
- 它是一个新式的
class
(基于object
) - 它定义了
__call__()
魔术方法 ,它返回一个布尔值
有一大组内置的预期条件类 。
我们来看看例子。 比方说,我们希望等到一个元素的文本将以所需的文本开始 :
from selenium.webdriver.support import expected_conditions as EC class wait_for_text_to_start_with(object): def __init__(self, locator, text_): self.locator = locator self.text = text_ def __call__(self, driver): try: element_text = EC._find_element(driver, self.locator).text return element_text.startswith(self.text) except StaleElementReferenceException: return False
用法:
WebDriverWait(driver, 10).until(wait_for_text_to_start_with((By.ID, 'myid'), "Hello, World!"))
根据文件 :
WebDriverWait默认每500毫秒调用ExpectedCondition,直到成功返回。 ExpectedCondition成功返回types为Boolean返回true或非null返回所有其他ExpectedConditiontypes的值。
事实上,如果你注释掉自定义的等待,你多次获得相同的URL应该给你一个提示。
在__call__()
你总是返回False
因为URL永远不会改变。 既然你返回False
,ExpectedCondition永远不会被满足,你会得到TimeoutException
。
因此,要么重新定义ExpectedCondition逻辑或testing一个不同的情况。
使用@alecxe描述的技术,但略微修改以接受接受元素而不是定位符的expected_conditions:(在这种情况下,因为没有selenium.webdriver.support.expected_conditions.invisibility_of(element)
,所以等待is_displayed()
方法表示False)
class wait_for_element_to_be_invisible(object): def __init__(self, element): self.element = element def __call__(self, driver): return not(self.element.is_displayed()) def test_collapsible_blocks_expand_or_collapse(self): self.browser.get(self.server_url+'/courses/1/') shadables = self.browser.find_elements_by_class_name('shade') for shadable in shadables: ## parent, then sibling element (*) shady_bit = shadable.find_element_by_xpath('../following-sibling::*') element = WebDriverWait(self.browser, 10).until( EC.visibility_of(shady_bit)) shadable.click() element = WebDriverWait(self.browser, 10).until( self.wait_for_element_to_be_invisible(shady_bit))
带有相关位的HTML片段是:
<h4 class="shadable"><span class="shade" title="Show/Hide">↓</span> <a href="/link/to/uri">Title of Section</a> </h4> <article class="abstract"> <p>Descriptive part which is shadable </p> </article>`