Exemplo n.º 1
0
class WordSpelling(BasePage):
    """单词拼写"""
    def __init__(self):
        self.result = ResultPage()
        self.get = GetAttribute()
        self.key = Keyboard()

    # 以下为 共有元素
    @teststeps
    def wait_check_page(self):
        """以“title:单词拼写”的ID为依据"""
        locator = (By.XPATH,
                   "//android.widget.TextView[contains(@text,'单词拼写')]")
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststeps
    def wait_check_play_page(self):
        """以“rate”的ID为依据"""
        locator = (By.XPATH, "//android.widget.TextView[contains(@resource-id,"
                   "'{}rate')]".format(self.id_type()))
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def rate(self):
        """获取作业数量"""
        rate = self.driver\
            .find_element_by_id(self.id_type() + "rate").text
        return rate

    @teststep
    def time(self):
        """获取作业时间"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "time").text
        return ele

    @teststep
    def click_voice(self):
        """页面内喇叭量按钮"""
        self.driver \
            .find_element_by_id(self.id_type() + "play_voice") \
            .click()

    @teststeps
    def word(self):
        """展示的Word"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        word = ele[1::2]
        print('study_word:', word)
        return word

    @teststep
    def explain(self):
        """展示的翻译"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_explain").text
        return word

    @teststep
    def finish_word(self):
        """完成答题 之后 展示的Word 前后含额外字符:aa"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        return word[1::2]

    # 默写模式 特有元素
    @teststeps
    def dictation_word(self):
        """展示的Word"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        value = ele[::2]
        return value

    @teststeps
    def dictation_word_judge(self):
        """判断是否展示Word"""
        try:
            self.driver \
                .find_element_by_id(self.id_type() + "tv_word")
            return True
        except Exception:
            return False

    @teststep
    def under_line(self):
        """展示的横线"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "underline")
        return ele

    @teststep
    def hint_button(self):
        """提示按钮"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "hint")
        return ele

    # 下一步 按钮之后 答案页展示的答案
    @teststep
    def mine_answer(self):
        """展示的Word  前后含额外字符:aa"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        return word[1::2]

    @teststep
    def question(self):
        """展示的翻译"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_explain").text
        return word

    @teststep
    def correct(self):
        """展示的答案"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_answer").text
        return word

    @teststeps
    def correct_judge(self):
        """判断 答案是否展示"""
        try:
            self.driver \
                .find_element_by_id(self.id_type() + "tv_answer")
            return True
        except Exception:
            return False

    # 默写模式 答案页特有元素
    @teststep
    def dictation_finish_word(self):
        """完成答题 之后 展示的Word  前后不含额外字符:aa"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        return word[::2]

    @teststep
    def dictation_mine_answer(self):
        """展示的Word  前后不含额外字符:aa"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_word").text
        return word[::2]

    # 以下为答案详情页面元素
    @teststeps
    def wait_check_detail_page(self):
        """以“answer”的ID为依据"""
        locator = (By.XPATH,
                   "//android.widget.TextView[contains(@resource-id," +
                   self.id_type() + "tv_answer)]")
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def result_voice(self, index):
        """语音按钮"""
        self.driver \
            .find_elements_by_id(self.id_type() + "iv_speak")[index] \
            .click()

    @teststep
    def result_answer(self, index):
        """单词"""
        ele = self.driver \
            .find_elements_by_id(self.id_type() + "tv_answer")[index].text
        return ele

    @teststep
    def result_explain(self, index):
        """解释"""
        ele = self.driver \
            .find_elements_by_id(self.id_type() + "tv_hint")[index].text
        return ele

    @teststep
    def result_mine(self, index):
        """我的"""
        ele = self.driver \
            .find_elements_by_id(self.id_type() + "iv_mine")[index]
        value = self.get.get_selected(ele)
        return value

    @teststeps
    def diff_type(self, tpe):
        """选择 不同模式小游戏的 游戏方法"""
        print(tpe)
        time.sleep(2)
        if tpe == '默写模式':
            answer = self.dictation_pattern()
        elif tpe == '自定义':
            answer = self.custom_pattern()
        else:  # 随机模式
            answer = self.random_pattern()
        return answer

    @teststeps
    def random_pattern(self):
        """《单词拼写 随机模式》 游戏过程"""
        if self.wait_check_page():  # 页面检查点
            if self.wait_check_play_page():
                var = []  # 随机消除的字母
                count = []  # 做错的题目
                answer = []  # return值 与结果页内容比对
                timestr = []  # 获取每小题的时间

                rate = self.rate()
                for i in range(int(rate)):
                    Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                    Homework().next_button_operate('false')  # 下一题 按钮 判断加 点击操作

                    explain = self.explain()  # 解释
                    word = self.word()  # 未缺失的字母
                    value = word_spelling_operate(explain)  # 数据字典

                    item = word.replace('_', '')
                    if self.is_alphabet(item):  # 未缺失的内容为字母
                        if value != word:  # 随机消除的字母消除了
                            for j in range(len(value)):
                                if value[j] != word[j]:
                                    print('缺失的字母:', value[j])
                                    var.append(j)
                                    self.keyboard_operate(
                                        j, value[j])  # 点击键盘 具体操作

                    answer.append(self.finish_word())  # 我的答案
                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断加 点击操作

                    self.result_operate(answer, count, i, timestr,
                                        self.mine_answer())  # 下一步按钮后的答案页面 测试
                    Homework().next_button_operate('true')  # 下一题 按钮 判断加 点击操作
                    print('======================================')

                Homework().now_time(timestr)  # 判断游戏界面 计时功能控件 是否在计时
                return rate, answer, var

    @teststeps
    def custom_pattern(self):
        """《单词拼写 自定义模式》 游戏过程"""
        if self.wait_check_page():  # 页面检查点
            if self.wait_check_play_page():
                count = []  # 做错的题目
                answer = []  # return值 与结果页内容比对
                timestr = []  # 获取每小题的时间
                rate = self.rate()
                for i in range(int(rate)):
                    Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                    Homework().next_button_operate('false')  # 下一题 按钮 判断加 点击操作

                    explain = self.explain()  # 解释
                    word = self.word()  # 未缺失的字母
                    value = word_spelling_operate(explain)  # 数据字典

                    item = word.replace('_', '')
                    if self.is_alphabet(item):  # 未缺失的内容为字母
                        if len(word) != 0:
                            if value != word:  # 自定义消除的字母消除了
                                for j in range(len(value)):
                                    if value[j] != word[j]:
                                        print('缺失的字母:', value[j])
                                        self.keyboard_operate(
                                            j, value[j])  # 点击键盘 具体操作
                            else:
                                print('❌❌❌ Error - 自定义消除的字母未消除', word)
                                for j in range(0, len(value) - 1):
                                    if value[j] != word[j]:
                                        print('❌❌❌ Error - 未自定义消除的字母%s也消除了' %
                                              value[j])

                    answer.append(self.finish_word())  # 我的答案
                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击

                    self.result_operate(answer, count, i, timestr,
                                        self.mine_answer())  # 下一步按钮后的答案页面 测试
                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击

                    print('======================================')

                Homework().now_time(timestr)  # 判断游戏界面 计时功能控件 是否在计时
                return rate, answer

    @teststeps
    def dictation_pattern(self):
        """《单词拼写 默写模式》 游戏过程"""
        if self.wait_check_page():  # 页面检查点
            if self.wait_check_play_page():
                count = []
                answer = []  # return值 与结果页内容比对
                timestr = []  # 获取每小题的时间
                rate = self.rate()
                for i in range(int(rate)):
                    Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                    Homework().next_button_operate('false')  # 下一题 按钮 判断 加点击

                    explain = self.explain()  # 解释
                    value = word_spelling_operate(explain)  # 数据字典

                    if self.dictation_word_judge():  # 默写模式 - 字母未全部消除
                        print('❌❌❌ Error - 单词拼写 默写模式 - 字母未全部消除')

                    if i in range(2, 5, 2):
                        hint = self.hint_button()  # 提示按钮
                        if self.get.get_enabled(hint) == 'true':
                            hint.click()  # 点击 提示按钮
                            if self.get.get_enabled(hint) != 'false':
                                print('❌❌❌ Error - 点击后提示按钮enabled属性为:',
                                      self.get.get_enabled(hint))

                            if self.dictation_word_judge():  # 出现首字母提示
                                word = self.dictation_word()
                                if len(word) == 1 and word == value[0]:
                                    print('点击提示出现首字母提示', word)
                                else:
                                    print('❌❌❌ Error - 点击提示未出现首字母提示')
                        else:
                            print('❌❌❌ Error - 提示按钮enabled属性为:',
                                  self.get.get_enabled(hint))

                    for j in range(len(value)):
                        self.keyboard_operate(j, value[j])  # 点击键盘 具体操作

                    answer.append(self.dictation_finish_word())  # 我的答案
                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击

                    self.result_operate(
                        answer, count, i, timestr,
                        self.dictation_mine_answer())  # 下一步按钮后的答案页面 测试
                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击
                    print('======================================')

                Homework().now_time(timestr)  # 判断游戏界面 计时功能控件 是否在计时
                return rate, answer

    @teststeps
    def keyboard_operate(self, j, value):
        """点击键盘 具体操作"""
        if j == 4:
            self.key.games_keyboard('capslock')  # 点击键盘 切换到 大写字母
            self.key.games_keyboard(value.upper())  # 点击键盘对应 大写字母
            self.key.games_keyboard('capslock')  # 点击键盘 切换到 小写字母
        else:
            self.key.games_keyboard(value)  # 点击键盘对应字母

    @teststeps
    def result_operate(self, answer, count, i, timestr, mine):
        """下一步按钮后的答案页面"""
        # mine 为 答案页面展示的 我的答题结果
        print('----------------------')
        result = answer[len(answer) - 1]
        print('我的答案:', result)
        print('我的答题结果:', mine)
        if self.correct_judge():  # 展示的答案元素存在说明回答错误
            correct = self.correct()  # 正确答案
            if len(mine) <= len(correct):  # 输入少于或等于单词字母数的字符
                if mine.lower() != result.lower():  # 展示的 我的答题结果 是否与我填入的一致
                    print('Error - 字符数少于或等于时:', mine.lower(), result.lower())
            else:  # 输入过多的字符
                if correct + mine[len(correct):].lower() != correct + result[
                        len(correct):].lower():  # 展示的 我的答题结果 是否与我填入的一致
                    print('Error - 字符输入过多时:',
                          correct + mine[len(correct):].lower(),
                          correct + result[len(correct):].lower())

            for k in range(len(correct)):  # 测试 答案判断是否正确
                if result[k] not in correct:
                    count.append(i)  # 做错的题目
                    break
        else:  # 回答正确
            if mine.lower() != result.lower():  # 展示的 我的答题结果 是否与我填入的一致
                print('Error - 展示的答题结果 与我填入的不一致:', mine.lower(),
                      result.lower())

        if i == 1:  # 第2题
            j = 0
            print('多次点击发音按钮:')
            while j < 4:
                print(j)
                self.click_voice()  # 多次点击发音按钮
                j += 1
            time.sleep(1)
        else:
            self.click_voice()  # 点击 发音按钮
        timestr.append(self.time())  # 统计每小题的计时控件time信息

    @teststeps
    def result_detail_page(self, rate):
        """查看答案 操作过程"""
        if self.result.wait_check_result_page():  # 结果页检查点
            self.result.check_result_button()  # 结果页 查看答案 按钮
            if self.result.wait_check_detail_page():
                print('======================================')
                print('查看答案:')
                self.error_sum(rate)
                time.sleep(2)
            print('==============================================')

    @teststeps
    def error_sum(self, rate):
        """查看答案 - 点击答错的题 对应的 听力按钮"""
        print('题数:', int(rate))
        for i in range(0, int(rate)):
            print('解释:', self.result_explain(i))  # 解释
            print('单词:', self.result_answer(i))  # 正确word
            print('对错标识:', self.result_mine(i))  # 对错标识
            print('-----------------------------------')
            self.result_voice(i)  # 点击发音按钮
        self.result.back_up_button()  # 返回结果页

    @teststeps
    def study_again(self, tpe):
        """再练一遍 操作过程"""
        if self.result.wait_check_result_page():  # 结果页检查点
            self.result.again_button()  # 结果页 再练一遍 按钮
            print('再练一遍:')
            self.diff_type(tpe)  # 不同模式 对应不同的游戏过程
Exemplo n.º 2
0
class Cloze(BasePage):
    """完形填空"""
    def __init__(self):
        self.get = GetAttribute()

    @teststeps
    def wait_check_page(self):
        """以“title:完形填空”的xpath-index为依据"""
        locator = (By.XPATH,
                   "//android.widget.TextView[contains(@text,'完形填空')]")
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststeps
    def wait_check_play_page(self):
        """以“rate”的ID为依据"""
        locator = (By.XPATH,
                   "//android.widget.TextView[contains(@resource-id,'{}rate')]"
                   .format(self.id_type()))
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def rate(self):
        """获取作业数量"""
        rate = self.driver \
            .find_element_by_id(self.id_type() + "rate").text
        return rate

    @teststep
    def font_middle(self):
        """第一个Aa"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "font_middle")

        return ele

    @teststep
    def font_large(self):
        """第二个Aa"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "font_large")
        return ele

    @teststep
    def font_great(self):
        """第三个Aa"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "font_great")
        return ele

    @teststep
    def dragger_button(self):
        """拖动按钮"""
        num = self.driver \
            .find_element_by_id(self.id_type() + "dragger")
        return num

    @teststeps
    def question(self):
        """题目"""
        num = self.driver \
            .find_element_by_id(self.id_type() + "question").text
        return num

    @teststeps
    def option_button(self, var):
        """选项"""
        ele = self.driver \
            .find_elements_by_xpath("//android.widget.TextView[contains(@text, '%s')]"
                                    "/following-sibling::android.widget.LinearLayout/android.widget.LinearLayout"
                                    "/android.widget.LinearLayout/android.widget.TextView" % var)
        item = []
        content = []
        for i in range(0, len(ele), 2):
            item.append(ele[i])
            content.append(ele[i + 1])
        print('选项个数:', len(item), len(content))
        return item, content

    @teststeps
    def option_content(self):
        """选项 内容"""
        ele = self.driver \
            .find_elements_by_id(self.id_type() + "tv_item")
        return ele

    @teststep
    def time(self):
        """获取作业时间"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "time").text
        return ele

    def options_view_size(self):
        """获取整个选项页面大小"""
        num = self.driver.find_element_by_id(self.id_type() + "option")
        var = num.size
        return var['height']

    @teststep
    def input_text(self):
        """输入框"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "cl_content")
        return ele

    @teststeps
    def get_input_bounds(self):
        """获取 输入框坐标"""
        ele = self.input_text()  # 输入框
        content = self.get.get_description(ele)
        item_x = re.match(".*\[(.*)\].*\[", content)  # x值
        item_y = re.match(".*\[(.*)\].*", content)  # y值
        x = item_x.group(1).split(',')  # 所有输入框y值的列表
        y = item_y.group(1).split(',')  # 所有输入框x值的列表
        size = ele.size
        return x, y, size

    @teststeps
    def get_result(self):
        """获取 输入框 的结果"""
        ele = self.input_text()  # 输入框
        content = self.get.get_description(ele)
        value = re.match("\\[(.+?)\\]", content)  # answer
        answer = value.group(1).split(',')  # 所有输入框值的列表
        print(answer)
        return answer

    @teststeps
    def cloze_operate(self):
        """《完形填空》 游戏过程"""
        if self.wait_check_page():
            if self.wait_check_play_page():
                result = []
                timestr = []  # 获取每小题的时间
                rate = self.rate()

                self.font_operate()  # Aa文字大小切换按钮 切换 及状态统计

                drag = self.dragger_button()  # 拖拽 拖动按钮
                loc = self.get_element_bounds(drag)
                size = self.options_view_size()  # 获取整个选项页面大小

                y = loc[3] - size * 4 / 3
                if loc[3] - size * 4 / 3 < 0:
                    y = 0
                self.driver.swipe(loc[2], loc[3], loc[2], y, 1000)  # 向上拖拽

                for i in range(int(rate)):
                    Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                    Homework().next_button_operate('false')  # 下一题 按钮 判断加 点击操作

                    if i == 4:
                        self.screen_swipe_up(0.5, 0.5, 0.25, 1000)

                    num = self.question()  # 题目
                    if int(re.sub("\D", "", num)) == i:  # 如果一次没滑动,再滑一次
                        self.screen_swipe_left(0.9, 0.8, 0.1, 2000)
                        num = self.question()  # 题目
                    print(num)

                    options = self.option_button(num)  # 四个选项
                    options[0][random.randint(0, len(options[0])) -
                               1].click()  # 随机点击选项
                    time.sleep(1)
                    for j in range(len(options[0])):
                        if self.get.get_selected(options[0][j]) == 'true':
                            print('选择的答案:', options[1][j].text)
                            result.append(options[1][j].text)
                            break

                    timestr.append(self.time())  # 统计每小题的计时控件time信息
                    self.screen_swipe_left(0.9, 0.8, 0.1, 2000)

                    if i == int(
                            rate) - 1:  # 最后一小题:1、测试滑动页面是否可以进入结果页   2、拖拽 拖动按钮
                        if not ResultPage().wait_check_result_page(
                                2):  # 结果页检查点
                            drag = self.dragger_button()  # 拖拽 拖动按钮
                            loc = self.get_element_bounds(drag)
                            self.driver.swipe(loc[2], loc[3], loc[2],
                                              loc[3] + size - 10,
                                              1000)  # 拖拽按钮到底部
                        else:
                            print('❌❌❌ Error - 滑动页面进入了结果页')

                    time.sleep(1)
                    print('================')

                time.sleep(1)
                content = self.get_result()  # 测试 是否答案已填入文章中
                if len(content) != len(result):
                    print('❌❌❌ Error -获取到的答案不一致', result, content)
                else:
                    for k in range(len(result)):
                        if content[k][
                                0] == ' ':  # 由于填入content-desc的数据会自动加一个空格,故去掉
                            content[k] = content[k][1:]
                        if content[k] != result[k]:
                            print('❌❌❌ Error - 填入的答案与选择的答案不一致', result[k],
                                  content[k])

                Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击
                Homework().now_time(timestr)  # 判断游戏界面 计时功能控件 是否在计时

    @teststeps
    def font_operate(self):
        """Aa文字大小切换按钮 状态判断 及 切换操作"""
        x = []
        y = []
        middle = self.font_middle()  # first
        large = self.font_large()  # second
        great = self.font_great()  # third

        i = 0
        j = 0
        while i < 3:
            bounds = self.get_input_bounds()  # 获取输入框坐标
            print(self.get.get_checked(middle), self.get.get_checked(large),
                  self.get.get_checked(great))

            if self.get.get_checked(middle) == 'false':
                if self.get.get_checked(large) == 'false':
                    x.insert(2, bounds[0][0])
                    y.insert(2, bounds[1][0])
                    print('当前选中的Aa按钮为第3个:', bounds[0][0], bounds[1][0])
                    j = 3
                else:
                    if self.get.get_checked(large) == 'true':
                        x.insert(1, bounds[0][0])
                        y.insert(1, bounds[1][0])
                        print('当前选中的Aa按钮为第2个:', bounds[0][0], bounds[1][0])
                        j = 2
            else:
                x.insert(0, bounds[0][0])
                y.insert(0, bounds[1][0])
                print('当前选中的Aa按钮为第1个:', bounds[0][0], bounds[1][0])
                j = 1

            if j == 1:
                large.click()
            elif j == 2:
                great.click()
            else:
                middle.click()
            i += 1
            print('--------------------------------------------')
            time.sleep(2)

        if not float(y[2]) > float(y[1]) > float(y[0]):
            print('❌❌❌ Error - Aa文字大小切换按钮:', y)
        print('==============================================')
class FlashCardPage(BasePage):
    """闪卡练习"""
    def __init__(self):
        self.get = GetAttribute()
        self.key = Keyboard()

    @teststeps
    def wait_check_page(self):
        """以“title:闪卡练习”的ID为依据"""
        locator = (By.XPATH,
                   "//android.widget.ImageView[contains(@resource-id,"
                   "'{}iv_star')]".format(self.id_type()))
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def wait_check_tip_num(self, num):
        """查看题目数量是否发生改变"""
        locator = (
            By.XPATH,
            "//android.widget.ImageView[contains(@text,'{}')]".format(num))
        try:
            WebDriverWait(self.driver, 20,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def click_star(self):
        """闪卡练习页面内 标星按钮"""
        self.driver \
            .find_element_by_id(self.id_type() + "iv_star") \
            .click()

    @teststep
    def click_voice(self):
        """闪卡练习页面内音量按钮"""
        self.driver \
            .find_element_by_id(self.id_type() + "play_voice") \
            .click()

    @teststep
    def rate(self):
        """获取作业数量"""
        rate = self.driver\
            .find_element_by_id(self.id_type() + "rate").text
        return rate

    # 以下为学习模式 特有元素
    @teststep
    def english_study(self):
        """Word"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_english").text
        return word

    @teststep
    def explain_study(self):
        """翻译"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "tv_chinese").text
        return word

    @teststep
    def pattern_switch(self):
        """闪卡练习页面内  全英/英汉模式切换 按钮"""
        self.driver \
            .find_element_by_id(self.id_type() + "iv_rotate")\
            .click()
        time.sleep(1)

    # 英汉模式 的例句
    @teststeps
    def wait_check_sentence_page(self, var=20):
        """以“例句”的ID为依据"""
        locator = (By.XPATH, "//android.widget.TextView[contains(@resource-id,"
                   "'{}sentence')]".format(self.id_type()))
        try:
            WebDriverWait(self.driver, var,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststeps
    def wait_check_explain_page(self, var=20):
        """以“例句解释”的ID为依据"""
        locator = (By.XPATH, "//android.widget.TextView[contains(@resource-id,"
                   "'{}sentence_explain')]".format(self.id_type()))
        try:
            WebDriverWait(self.driver, var,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststep
    def sentence_study(self):
        """例句"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "sentence").text
        print('例句:', word)

    @teststep
    def sentence_explain_study(self):
        """例句翻译"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "sentence_explain").text
        print('例句解释:', word)

    @teststep
    def sentence_author_study(self):
        """例句 提供老师"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "author").text
        print(word)

    @teststeps
    def click_blank(self):
        """点击空白处"""
        ClickBounds().click_bounds(430, 800)
        print('点击空白处,切换双页面:')
        time.sleep(1)

    # 以下为抄写模式 特有元素
    @teststep
    def word_copy(self):
        """闪卡练习- 抄写模式 内展示的Word"""
        ele = self.driver\
            .find_element_by_id(self.id_type() + "tv_word")
        return ele.text

    @teststep
    def english_copy(self):
        """单页面内 答题框填入的Word"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "english").text
        return word

    @teststep
    def explain_copy(self):
        """闪卡练习内展示的翻译"""
        word = self.driver \
            .find_element_by_id(self.id_type() + "chinese").text
        return word

    # 以下为闪卡练习 结果页
    @teststeps
    def wait_check_result_page(self, var=10):
        """以“title:答题报告”的ID为依据"""
        locator = (By.XPATH,
                   "//android.widget.TextView[contains(@text,'完成学习')]")
        try:
            WebDriverWait(self.driver, var,
                          0.5).until(lambda x: x.find_element(*locator))
            return True
        except:
            return False

    @teststeps
    def finish_study(self):
        """完成学习"""
        ele = self.driver \
            .find_element_by_xpath("//android.widget.TextView[contains(@index,0)]").text
        print(ele)
        return ele

    @teststeps
    def study_sum(self):
        """eg: study_sum:6个内容,0标记★;抄写模式"""
        ele = self.driver \
            .find_element_by_id(self.id_type() + "study_sum").text
        print(ele)
        return ele

    @teststep
    def study_again_button(self):
        """再练一遍"""
        self.driver \
            .find_element_by_id(self.id_type() + "textView") \
            .click()

    @teststep
    def star_again_button(self):
        """标星内容再练一遍"""
        self.driver \
            .find_element_by_id(self.id_type() + "tv_star_en") \
            .click()

    @teststep
    def star_button(self):
        """五星按钮"""
        ele = self.driver \
            .find_elements_by_id(self.id_type() + "iv_select")
        return ele

    @teststep
    def voice_button(self, index):
        """语音按钮"""
        self.driver \
            .find_elements_by_id(self.id_type() + "iv_voice")[index] \
            .click()

    @teststep
    def result_word(self):
        """展示的Word"""
        ele = self.driver.find_elements_by_id(self.id_type() + "tv_word")
        return ele

    @teststep
    def result_explain(self):
        """展示的  解释"""
        word = self.driver \
            .find_elements_by_id(self.id_type() + "tv_explain")
        return word

    @teststeps
    def study_pattern(self):
        """《闪卡练习 学习模式》 游戏过程"""
        if self.wait_check_page():
            answer = []  # return值 与结果页内容比对
            rate = self.rate()
            for i in range(int(rate)):
                Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                Homework().next_button_judge('true')  # 下一题 按钮 状态判断

                # self.click_voice()  # 听力按钮
                if i in (2, 5):  # 第3、6题  进入全英模式
                    self.pattern_switch()  # 切换到 全英模式
                    print('切换到 全英模式:')
                    if self.wait_check_sentence_page(5):
                        self.sentence_study()  # 例句
                        self.sentence_author_study()  # 例句作者

                    word = self.english_study()  # 单词
                    print('单词:%s' % word)

                    self.pattern_switch()  # 切换到 英汉模式
                else:
                    if self.wait_check_explain_page(5):
                        self.sentence_study()  # 例句
                        self.sentence_explain_study()  # 例句解释
                        self.sentence_author_study()  # 例句作者

                    word = self.english_study()  # 单词
                    explain = self.explain_study()  # 解释
                    print('单词:%s, 解释:%s' % (word, explain))

                answer.append(self.english_study())

                if i in range(1, 9, 2):  # 点击star按钮
                    self.click_star()
                    # if i == 1:
                    #     self.tips_operate()

                if i == 3 and i != int(rate) - 1:  # 第四题 滑屏进入下一题
                    self.screen_swipe_left(0.9, 0.5, 0.1, 1000)
                    time.sleep(1)
                else:
                    if i == int(rate) - 1:  # 最后一题 尝试滑屏进入结果页
                        self.screen_swipe_left(0.9, 0.5, 0.1, 1000)
                        if self.wait_check_result_page(5):
                            print('❌❌❌ Error - 滑动页面进入了结果页')

                    Homework().next_button_operate('true')  # 下一题 按钮 状态判断 加点击
                    time.sleep(1)
                print('-------------------------')
            print('=================================')
            return rate, answer

    @teststeps
    def copy_pattern(self):
        """《闪卡练习 抄写模式》 游戏过程"""
        if self.wait_check_page():  # 页面检查点
            answer = []  # return值 与结果页内容比对
            rate = self.rate()
            for i in range(int(rate)):
                if self.wait_check_page():
                    Homework().rate_judge(rate, i)  # 测试当前rate值显示是否正确
                    right_word = self.word_copy()
                    word = list(right_word)  # 展示的Word -- 转化为list形式
                    answer.append(right_word)
                    print("第%s题,单词是:%s" % (i + 1, right_word))
                    self.voice_operate(i)  # 听力按钮

                    for j in range(len(word)):
                        print(word[j])
                        if j == 5:
                            self.key.games_keyboard(
                                'capslock')  # 点击键盘 切换到 大写字母
                            self.key.games_keyboard(
                                word[j].upper())  # 点击键盘对应 大写字母
                        else:
                            if j == 6:
                                self.key.games_keyboard(
                                    'capslock')  # 点击键盘 切换到 小写字母
                            self.key.games_keyboard(
                                word[j].lower())  # 点击键盘对应字母
                    print('--------------------------------')
                time.sleep(4)
            print('=================================')
            return rate, answer

    @teststeps
    def voice_operate(self, i):
        """听力按钮 操作"""
        if i == 2:  # 第3题
            j = 0
            print('多次点击发音按钮:')
            while j < 4:
                self.click_voice()  # 多次点击发音按钮
                j += 1
            time.sleep(1)
        else:
            self.click_voice()  # 点击 发音按钮

    @teststeps
    def result_page(self, i, answer):
        """结果页操作"""
        self.finish_study()  # 完成学习
        self.study_sum()  # 学习结果

        word = self.result_word()
        print('判断是否滑动:', i)
        if len(word) <= int(i):
            # self.result_operate(int(i)-1, answer)
            # self.screen_swipe_up(0.5, 0.75, 0.35, 1000)
            self.result_operate(i, answer, int(i))
        else:
            name = word[len(word) - 1].text
            self.result_operate(len(word) - 1, answer)
            self.screen_swipe_up(0.5, 0.75, 0.35, 1000)

            index = self.result_operate_swipe(name)
            for j in range(5):
                if len(index) == 0:
                    self.screen_swipe_down(0.5, 0.75, 0.65, 1000)
                    index = self.result_operate_swipe(name)
                else:
                    break
            word = self.result_word()
            self.result_operate(len(word), answer, index[0])
        print('=================================')

    @teststeps
    def result_operate_swipe(self, name):
        """滑屏操作"""
        index = []
        word = self.result_word()
        for j in range(len(word)):
            if word[j].text == name:
                index.append(j)
                break
        return index

    @teststeps
    def result_operate(self, index, answer, k=0):
        """结果页 具体操作"""
        word = self.result_word()
        for i in range(len(word)):
            print(word[i].text, answer[i])
            if word[i].text != answer[i]:  # 结果页 展示的word与题目中是否一致
                print('❌❌❌ Error 查看答案页 展示的word与题中不一致')

        for index in range(k, int(index), 3):  # 点击 结果页 听力按钮
            self.voice_button(index)  # 结果页 - 听力按钮
            self.star_button()[index].click()  # 结果页 star 按钮

    @teststeps
    def selected_sum(self):
        """标星的数目统计"""
        var = self.star_button()  # 结果页star按钮
        ele = []  # 结果页标星的作业数
        for i in range(len(var)):
            if self.get.get_selected(var[i]) == 'true':
                ele.append(i)

        if len(ele) == 0:  # 结果页标星的作业数为0,则执行以下操作
            print('结果页标星的作业数为0, 点击star按钮:')
            for index in range(0, len(var), 2):
                self.star_button()[index].click()  # 结果页 star 按钮

            ele = []  # 结果页标星的作业数
            for i in range(len(var)):
                if self.get.get_selected(var[i]) == 'true':
                    ele.append(i)

            self.study_sum()  # 学习情况
            print('----------------')

        print('star按钮数目:', len(var))
        print('标星数:', len(ele))
        print('========================')
        return len(ele)