如何从预期的条件调用函数

时间:2016-04-25 10:20:48

标签: python-3.x selenium automated-tests

我最近开始学习邮件服务gmail示例的自动化测试。我试图通过循环调用验证码,但不理解预期的条件是如何工作的。我如何正确调用函数完成程序?对不起英语。

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


class my:
    def loop_send_keys(self):
        while (True):

            self.email.send_keys("a")
            self.email.submit()
            if (self.captcha.is_displayed()):
                return self.driver.find_elements(self, By.ID, "captcha-img")  # Problem in this line

    def launch(self):
        self.a = False
        driver = webdriver.Firefox()
        self.driver = driver
        driver.get("https://mail.google.com/")
        driver.implicitly_wait(4)
        self.email = driver.find_element_by_name("Email")
        self.email.send_keys("sndb11")
        self.captcha = self.driver.find_element_by_id("captcha-img")
        WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located(By.ID, self.loop_send_keys())  # and this
        )


a = my()
a.launch()

1 个答案:

答案 0 :(得分:0)

首先,我建议您阅读that教程,您对硒的使用感到困惑。

link 1: (implicit wait doc)

link 2: (until method doc)

#!/usr/bin/python3.4

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


class my:
    def loop_send_keys(self):
        # here self is the driver (aka webdriver.Firefox()) (see link 2)
        # do you really think that method should be in that class?
        # at runtime the code executed is my.loop_send_keys(driver_instance)
        # please consider moving that method outside that class,
        # a module function would be great!

        # You don not need a while loop here, the WebDriverWait( ).until( )
        # statement will call that method until return value is not
        # False -> (see link 2)

        self.find_element_by_id("next").submit()
        try:
            self.find_element_by_id("captcha-img")
        except selenium.common.exceptions.NoSuchElementException:
            # At least a return False statement should exist in that method
            # (see link 2)
            return False
        else:
            # Returning the return value of find_elements makes no sense, since
            # you can not use that value (it is consumed by the until method)
            # And why did you use a find elements method if you were looking
            # for just an element?
            return True

    def launch(self):
        # are you using it in the question? if not keep it away
        # self.a = False

        # driver = webdriver.Firefox()
        # self.driver = driver
        # why not simply ...
        self.driver = webdriver.Firefox()
        # ... ?

        # You should call the implicitly wait before getting to the URL,
        # since you need to call it one time per session -> (see link 1)
        self.driver.implicitly_wait(10)
        self.driver.get("https://mail.google.com/")

        try:
            # all methods find_element_by_* can raise NoSuchElementException
            self.email = self.driver.find_element_by_name("Email")
        except selenium.common.exceptions.NoSuchElementException:
            print("Element with name Email not found")
            return

        # please ask generic questions, 'sndb11' does not make any sense
        self.email.send_keys("not_existing_email\n")

        # You should try to find the element after you have waited for it

        # Until method needs only a method as argument -> (see link 2)
        # Why did you use a presence_of_all_elements_located method ?

        # That code does what you wanted:
        WebDriverWait(self.driver, 10).until(my.loop_send_keys)
        # but its really awful, why not simply doing:
        # WebDriverWait(driver, 10).until(
        #              EC.presence_of_element_located((By.ID, "captcha-img")))
        # and getting rid of my.loop_send_keys method ?

        try:
            self.captcha = self.driver.find_element_by_id("captcha-img")
            # when you have that element do whatever you want with it
            print("here is the representation of self.captcha:"\
                  "\n\t{}".format(repr(self.captcha)))
            # but be careful that probably is not visible
            if not self.captcha.is_displayed():
                print("WARNING: self.captcha element is not visible !!")
        except selenium.common.exceptions.NoSuchElementException:
            print("timeout of 10 seconds expired")

if __name__ == "__main__":
    a = my()
    a.launch()

注意:在提问时请尽量更加清晰准确。