【问题标题】:Selenium waitForElement硒等待元素
【发布时间】:2011-12-08 13:39:07
【问题描述】:

如何编写函数让 Selenium 在 Python 中等待一个只有类标识符的表?我在学习使用 Selenium 的 Python webdriver 函数时遇到了麻烦。

【问题讨论】:

    标签: python selenium selenium-webdriver automation automated-tests


    【解决方案1】:

    我希望这可能会有所帮助:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as ec
    
    driver = webdriver.Chrome()
    driver.get(myURL)
    wait = WebDriverWait(driver, 10) 
    
    wait.until(ec.presence_of_element_located((By.XPATH, myXPATH)))
    

    我建议您阅读this 文章以使其更清楚。

    【讨论】:

      【解决方案2】:
      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      from selenium.webdriver.support.ui import WebDriverWait
      
      
      # wait until present
      WebDriverWait(driver, waittime).until(
          EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
      )
      
      # wait until visible
      WebDriverWait(driver, waittime).until(
          EC.visibility_of_element_located((By.CSS_SELECTOR, css_selector))
      )
      

      【讨论】:

        【解决方案3】:

        我找到了一种更简单的方法来使用自定义函数来构建它,它本质上是递归的

        from selenium import webdriver
        import time
        
        def wait_element_by_id(id_value):
            try:
                elem = driver.find_element_by_id(id_value)
            except:
                time.sleep(2)
                print 'Waiting for id '+id_value
                wait_element_by_id(id_value)
        

        您可以根据需要将find_element_by_id 替换为find_element_by_namefind_element_by_tag_name

        【讨论】:

        • 为什么使用递归而不是while循环?
        【解决方案4】:

        希望这会有所帮助

        from selenium import webdriver
        from selenium.webdriver.support import expected_conditions as EC
        from selenium.webdriver.support.wait import WebDriverWait
        from selenium.webdriver.common.by import By   
        
        
        driver = webdriver.Firefox()
        driver.get('www.url.com')
        
        try:
            wait = driver.WebDriverWait(driver,10).until(EC.presence_of_element_located(By.CLASS_NAME,'x'))
        except:
            pass
        

        【讨论】:

          【解决方案5】:

          您可以将此功能修改为所有类型的元素。以下仅用于类元素:

          其中“driver”是驱动程序,“element_name”是您要查找的类名,“sec”是您愿意等待的最大秒数。

          def wait_for_class_element(driver,element_name,sec):
          
              for i in range(sec):        
                  try:
                      driver.find_element_by_class_name(element_name)
                      break
                  except:        
                      print("not yet")
                      time.sleep(1)
          

          【讨论】:

            【解决方案6】:

            更简单的解决方案:

                from selenium.webdriver.common.by import By    
                import time
            
                while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0:
                    time.sleep(100)
            

            【讨论】:

              【解决方案7】:

              Selenium 2 的 Python 绑定有一个名为 expected_conditions.py 的新支持类,用于执行各种操作,例如测试元素是否可见。我是available here.

              注意:截至 2012 年 10 月 12 日,上述文件位于主干中,但尚未包含在最新下载中,仍为 2.25。目前,在发布新的 Selenium 版本之前,您可以暂时将此文件保存在本地,并将其包含在您的导入中,就像我在下面所做的那样。

              为了让生活更简单一些,您可以将这些预期条件方法中的一些与 Selenium wait until 逻辑结合起来,制作一些非常方便的功能,类似于 Selenium 1 中可用的功能。例如,我将其放入我的基础我所有的 Selenium 测试类都扩展了名为 SeleniumTest 的类:

              from selenium.common.exceptions import TimeoutException
              from selenium.webdriver.common.by import By
              import selenium.webdriver.support.expected_conditions as EC
              import selenium.webdriver.support.ui as ui
              
              @classmethod
              def setUpClass(cls):
                  cls.selenium = WebDriver()
                  super(SeleniumTest, cls).setUpClass()
              
              @classmethod
              def tearDownClass(cls):
                  cls.selenium.quit()
                  super(SeleniumTest, cls).tearDownClass()
              
              # return True if element is visible within 2 seconds, otherwise False
              def is_visible(self, locator, timeout=2):
                  try:
                      ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
                      return True
                  except TimeoutException:
                      return False
              
              # return True if element is not visible within 2 seconds, otherwise False
              def is_not_visible(self, locator, timeout=2):
                  try:
                      ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
                      return True
                  except TimeoutException:
                      return False
              

              然后您可以像这样在测试中轻松使用它们:

              def test_search_no_city_entered_then_city_selected(self):
                  sel = self.selenium
                  sel.get('%s%s' % (self.live_server_url, '/'))
                  self.is_not_visible('#search-error')
              

              【讨论】:

              【解决方案8】:

              如果我对 selenium 命令一无所知,我会使用 selenium web idea RC 和 firefox。您可以在组合框中选择和添加命令,完成测试用例后,您可以导出不同语言的测试代码。比如java、ruby、phyton、C#等。

              【讨论】:

                【解决方案9】:

                您总是可以在循环中使用短暂的睡眠并将您的元素 id 传递给它:

                def wait_for_element(element):
                     count = 1
                     if(self.is_element_present(element)):
                          if(self.is_visible(element)):
                              return
                          else:
                              time.sleep(.1)
                              count = count + 1
                     else:
                         time.sleep(.1)
                         count = count + 1
                         if(count > 300):
                             print("Element %s not found" % element)
                             self.stop
                             #prevents infinite loop
                

                【讨论】:

                • 这实际上是 WebdriverWait 所做的 :)
                【解决方案10】:

                来自Selenium Documentation PDF

                import contextlib
                import selenium.webdriver as webdriver
                import selenium.webdriver.support.ui as ui
                
                with contextlib.closing(webdriver.Firefox()) as driver:
                    driver.get('http://www.google.com')
                    wait = ui.WebDriverWait(driver,10)
                    # Do not call `implicitly_wait` if using `WebDriverWait`.
                    #     It magnifies the timeout.
                    # driver.implicitly_wait(10)  
                    inputElement=driver.find_element_by_name('q')
                    inputElement.send_keys('Cheese!')
                    inputElement.submit()
                    print(driver.title)
                
                    wait.until(lambda driver: driver.title.lower().startswith('cheese!'))
                    print(driver.title)
                
                    # This raises
                    #     selenium.common.exceptions.TimeoutException: Message: None
                    #     after 10 seconds
                    wait.until(lambda driver: driver.find_element_by_id('someId'))
                    print(driver.title)
                

                【讨论】:

                【解决方案11】:

                由于python selenium 驱动程序不支持此功能,因此我为python 实现了以下wait_for_condition。

                def wait_for_condition(c):
                for x in range(1,10):
                    print "Waiting for ajax: " + c
                    x = browser.execute_script("return " + c)
                    if(x):
                        return
                    time.sleep(1)
                

                用作

                等待 ExtJS Ajax 调用未挂起:

                wait_for_condition("!Ext.Ajax.isLoading()")
                

                设置了一个 Javascript 变量

                wait_for_condition("CG.discovery != undefined;")
                

                等等

                【讨论】:

                • 哇哦!这就像一个冠军:wait_for_condition("$().active == 0")
                【解决方案12】:

                如果这有帮助...

                在 Selenium IDE 中,我添加了... 命令:waitForElementPresent 目标://table[@class='pln']

                然后我做了 File>Export TestCase As Python2(Web Driver),它给了我这个...

                def test_sel(self):
                    driver = self.driver
                    for i in range(60):
                        try:
                            if self.is_element_present(By.XPATH, "//table[@class='pln']"): break
                        except: pass
                        time.sleep(1)
                    else: self.fail("time out")
                

                【讨论】:

                  【解决方案13】:

                  Wait Until Page Contains Element 与正确的XPath 定位器一起使用。例如,给定以下 HTML:

                  <body>
                    <div id="myDiv">
                      <table class="myTable">
                        <!-- implementation -->
                      </table>
                    </div>
                  </body>
                  

                  ...您可以输入以下关键字:

                  Wait Until Page Contains Element  //table[@class='myTable']  5 seconds
                  

                  除非我错过了什么,否则没有必要为此创建新函数。

                  【讨论】:

                    【解决方案14】:

                    我在以下方面取得了很好的经验:

                    • time.sleep(秒)
                    • webdriver.Firefox.implicitly_wait(秒)

                    第一个很明显 - 只需等待几秒钟即可。

                    对于我所有的 Selenium 脚本,当我在笔记本电脑上运行它们时,sleep() 只需几秒钟(范围从 1 到 3)就可以工作,但在我的服务器上等待的时间范围更广,所以我使用了 implicitly_wait( ) 也。我一般用implicitly_wait(30),真的够用了。

                    隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用的)时轮询 DOM 一段时间。默认设置为 0。一旦设置,就会为 WebDriver 对象实例的生命周期设置隐式等待。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-06-13
                      • 1970-01-01
                      • 2013-01-01
                      • 2019-02-19
                      相关资源
                      最近更新 更多