I'm trying to write my own expected condition. What I need... I have an iframe. and I also have an image in it. I want to continue processing when image's scr will change. What I did:
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
and later in the code I have:
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
This code works, but returns the same url multiple times. The problem is when I uncomment url_changed_condition
it falls with TimeoutException
in(current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))
The line below it works fine... I don't get it.
The wait applies the condition which tries finding the web element, depending on its status. If the condition can find the element, it returns the element as result. If it cannot find the element, the wait tries the condition again after a short delay.
Explicit Wait in SeleniumIf one sets an implicit wait command, then the browser will wait for the same time frame before loading every web element. This causes an unnecessary delay in executing the test script. Explicit wait is more intelligent, but can only be applied for specified elements.
An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. This syntax should be used for python: self.driver.implicitly_wait(10) # seconds.
Looks like this topic misses an example of a Custom Expected Condition.
It is actually pretty easy. First of all, what is an Expected Condition in Python selenium bindings:
class
(based on object
)__call__()
magic method defined which returns a boolean There is a big set of built-in expected condition classes.
Let's work through example. Let's say we want to wait until an element's text will start with a desired text:
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
Usage:
WebDriverWait(driver, 10).until(wait_for_text_to_start_with((By.ID, 'myid'), "Hello, World!"))
Using the technique described by @alecxe , but modified slightly to cope with the expected_conditions which accept an element instead of a locator:
(In this case, since there is no selenium.webdriver.support.expected_conditions.invisibility_of(element)
, I'm waiting for the is_displayed()
method to signal 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))
The HTML fragment with the relevant bits of the DOM is:
<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>`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With