当前位置: 首页 > 面试题库 >

如何通过Selenium和WebDriver等待JavaScript __doPostBack调用

云浩然
2023-03-14
问题内容

我在尝试通过Selenium / Python自动化同时尝试填写网站上的两个字段时遇到一种罕见的问题。我的脚本填写了第一个字段,即 ORIGIN
CITY
很好。我已经为第二个字段 DELIVERY ADDRESS 引入了 WebDriverWait 。 __

我猜想,甚至在诱使服务员之前,“ 交付地址” 字段都可以 单击

但是 ORIGIN CITY 字段具有通过事件关联的 JavaScriptonchange,如下所示:

onchange="javascript:setTimeout('__doPostBack(\'DrpCity\',\'\')', 0)"

起源城市HTML:

<li>

  <div class="form-group">

    <select name="DrpCity" onchange="javascript:setTimeout('__doPostBack(\'DrpCity\',\'\')', 0)" id="DrpCity" class="inputStyle">

        <option selected="selected" value="0">Origin City</option>

        <option value="3">Bangalore</option>

        <option value="6">Chennai</option>

        <option value="8">Delhi - NCR</option>

        <option value="10">Hyderabad</option>

        <option value="7">Kochi</option>

        <option value="12">Kolkata</option>

        <option value="13">Mumbai</option>

        <option value="15">Pune</option>



    </select>

    <span id="ReqCity" style="color:Red;visibility:hidden;">Select your city !</span>

  </div>

</li>

送货地址HTML:

<li>

  <div class="form-group">

    <div class="" id="div_AddPopup" style="display: none;">

      *Cars will not be delivered at Metro Stations, Malls or Public Place.

    </div>

    <input name="txtPickUp" type="text" id="txtPickUp" class="inputStyle locMark" placeholder="Delivery Address" onfocus="showOnKeyPress(); return true;" onblur="hideOnKeyPress(); return true;">



    <span id="ReqPickUp" style="color:Red;visibility:hidden;">Enter Delivery Address !</span>

  </div>

</li>

一旦 JavaScript的 完成它清除了从文本 送货地址 字段。

我确实将Java Client的 ExpectedConditions 视为 jsReturnsValue ,而 Selenium Python
Client
则没有。

网址:https :
//www.avis.co.in/

我的代码:

    from selenium import webdriver
    from selenium.webdriver.support.ui import Select
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    driver = webdriver.Firefox()
    driver.get("https://www.avis.co.in")
    mySelect = Select(driver.find_element_by_id("DrpCity"))
    mySelect.select_by_visible_text("Pune")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"//input[@id='txtPickUp']"))).send_keys("XYZ")

任何建议都会有所帮助。


问题答案:

我发现,处理这些JS最简单的方法postbacks,就是等待受影响的元素 负载陈旧 或无法找到。

这是一个示例函数

def waitForElementRemoved(Element, WaitCount, WaitTime):
    ElementRemoved = False
    WaitTry = 0
    while not ElementRemoved:
        try:
            if WaitTry > WaitCount:
                raise Exception("Element not removed from page in alloted time")
            Test = Element.text
            WaitTry += 1
            time.sleep(WaitTime)
        except (NoSuchElementException, StaleElementReferenceException):
            ElementRemoved = True

然后,我将选择一个受此影响的元素postback load并将其与一些计时参数一起传递给函数。

如:

driver = webdriver.Firefox()
driver.get("https://www.avis.co.in")
removedElement = driver.find_element_by_id("DrpCity")
mySelect = Select(driver.find_element_by_id("DrpCity"))
mySelect.select_by_visible_text("Pune")
waitForElementRemoved(removedElement, 10, .5)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='txtPickUp']"))).send_keys("XYZ")

我不知道这是否是处理JavaScript 事件的 最佳 方法onchange load,但就我而言,它非常有效。

为了补充这个答案 :我发现在有多个加载事件时, 等到元素变旧
并不总是有效,我发现使用该方法以及下面的代码可以更有效地确保这些动态加载事件已完成:(我改编了
HERE的以下代码)

# Wait for AJAX (Jquery or JS) dynamic page load events
class DynamicLoadState:
    def __call__(self, driver):
        LoadComplete = False
        JQueryLoadComplete = False
        JSLoadComplete = False
        try:
            if driver.execute_script("return jQuery.active") == 0: JQueryLoadComplete = True
        except Exception:
            # JQuery is not present on page
            JQueryLoadComplete = True
        if driver.execute_script("return document.readyState") == 'complete': JSLoadComplete = True
        if JQueryLoadComplete and JSLoadComplete: LoadComplete = True
        return LoadComplete

def WaitForDynamicLoad(driver, WaitTime):
    WebDriverWait(driver, WaitTime).until(DynamicLoadState())

# Use the first method of waiting for the element to go stale
# then run this to make sure all loading is completed

WaitForDynamicLoad(driver, Counts.WaitTime)

希望这有助于防止time.sleep()将来有人使用页面加载!



 类似资料:
  • 问题内容: 我正在使用Selenium 2 WebDriver来测试使用AJAX的UI。 有没有一种方法可以使驱动程序稍稍等待Ajax请求将完成。 基本上我有这个: 问题答案:

  • 我有一个打开浏览器的ruby脚本。我把它设置为先打开Firefox,然后再打开Chrome,如果FF因为某种原因失败了,比如FF得到了更新,Selenium还没有赶上。 等待函数/定义对FF很好,但总是中断。以下是Chrome浏览器启动的相关代码: 我对Selenium还是相当陌生,我使用了等待。在声明如下内容后,直到命令: 以上代码行在Firefox中运行良好。但是,我想用FF和Chrome运行

  • 我如何用一个显式的替换这个隐式的等待呢? driver=新ChromeDriver(功能); driver.manage().DeleteAllCookies();

  • 问题内容: 我正在浏览一个Web应用程序,如果尝试单击某个元素之后才能与之交互,则该Web应用程序通常会引发错误。 使用Selenium WebDriver(java)时,我可以轻松解决此问题: 但是,我试图使用Selenium类型库在VBA中编写脚本,尽管尝试了许多不同的方法,但我唯一的成功是: 有人告诉我,应该尽可能避免这样做。如果有人可以建议如何将Java转换为VBA或提供任何其他解决方案,

  • 等待元素出现在网页上的最佳方式是什么?我已经读到,我们可以使用隐式等待和功能,如网络驱动程序wait,流利的等待等,最后但不是最不重要的线程.sleep()...我使用最多,但想停止使用。 我的场景: 用户登录到网站…网站检查凭据,并以叠加的形式向用户提供报价(一种弹出窗口,但不是单独的窗口)。我需要验证叠加图上的文字。用户登录和显示覆盖之间存在时间间隔。最好的方法是什么,以便硒只等待元素不可见的

  • 问题内容: 有没有办法使用PageFactory批注来等待Selenium中不存在的元素? 使用时: 找到元素,然后: 我会得到: 我可以使用以下方法执行我需要做的事情: 但是,我希望能够使用PageFactory批注以使框架保持一致。有没有办法做到这一点? 问题答案: 期望定位器,但是您正在发送网络元素,这就是为什么它会引发错误。您可以通过使用以下方法检查webelement列表来执行操作: 更