def test_Xiaowei_Disconnect_Cycle_While_Music_Is_Streaming_01(automation_xiaowei_connect): dut = automation_xiaowei_connect[0] phone = automation_xiaowei_connect[1] assert phone.xiaowei.verify_device_icon(), "Xiaowei connection fail" test_step(1, "Launch QQ music", dut) assert phone.launch_application(PhoneAppType.QQMUSIC), "Failed to launch QQ music" test_step(2, "Play a music in QQ music", dut) assert phone.qqmusic.play_music(), "Failed to play music" assert dut.status.get_sink_state() == SinkStates.A2DP_STREAMING, "The music was not played" test_step(3, "Launch xiaowei", dut) assert phone.launch_application(PhoneAppType.XIAOWEI), "Failed to switch to Xiaowei" cycle = 20 for i in range(cycle): logger.info("Test disconnect xiaowei and reopen for %d times, %d" % (cycle, i + 1)) assert dut.status.get_sink_state() == SinkStates.A2DP_STREAMING, "The music was not played" test_step(4, "Disconnect dut", dut) assert phone.xiaowei.disconnect_device(), "Failed to disconnect dut" test_step(5, "Close xiaowei APP", dut) assert phone.xiaowei.close_app(), "Failed to close xiaowei" test_step(6, "Re-open xiaowei APP", dut) assert phone.xiaowei.launch_app(), "Failed to re-open Xiaowei" test_step(7, "Verify prompt and accept it", dut) assert phone.xiaowei.verify_connection_prompt(), "Failed to verify connection prompt" assert phone.xiaowei.accept_connection_prompt(), "Failed to accept connection prompt" test_step(8, "Verify if xiaowei connect to dut", dut) assert phone.xiaowei.verify_device_icon(), "Failed to connect with dut" test_step(9, "Close QQ music", dut) assert phone.qqmusic.terminate_app(), "Failed to close QQ music" wait(20) assert dut.status.get_sink_state() == SinkStates.CONNECTED, "Failed to close QQ music"
def launch_settings_app(self, driver=None): """ Launch settings application :param:None :return:None :raises:None """ status = '' is_application_launched = False self.__initialize_variable_of_settings() try: if driver: self.driver = driver else: self.driver = self.mobile_driver_factory_object.get_driver( get_appium_server_ip(), self.phone_info.appium_port, self.phone_info.platform_name, self.phone_info.os_version, self.phone_info.config_name, self.phone_info.uuid, self.package_name, self.activity_name, self.phone_info.wda_local_port) wait(5, "To Settle Down App After Launching") is_application_launched = True except Exception as e: logger.error('Driver launch Fail on {}'.format( self.phone_info.bluetooth_name)) return is_application_launched
def wifi_on(self): if self.phone_info.phone_type == PhoneType.ANDROID: ret = subprocess.Popen(self.wifi_on_command, shell=True) ret.wait() if ret.returncode == 0: return True else: return False else: if self.go_to_test_screen(self.go_to_wifi_setting_screen): if self.verify_setting(self.wifi_switch_on): self.driver.appium_driver.back() return True else: if self.perform_setting(self.wifi_switch): wait(2) if self.verify_setting(self.wifi_switch_on): self.driver.appium_driver.back() return True else: self.driver.appium_driver.back() return False else: self.driver.appium_driver.back() return False else: self.driver.appium_driver.back() return False
def launch_qqmusic_app(self, driver=None): """ Launch willow application :param:None :return:None :raises:None """ try: wait(5) self.__initialize_variable_of_qqmusic_app() if driver: self.driver = driver else: self.driver = self.mobile_driver_factory_object.get_driver(get_appium_server_ip(), self.phone_info.appium_port, self.phone_info.platform_name, self.phone_info.os_version, self.phone_info.config_name, self.phone_info.uuid, self.package_name, self.activity_name, self.phone_info.wda_local_port) except Exception as e: logger.error(f'Driver launch Fail on {self.phone_info.bluetooth_name}') logger.error(repr(e)) return False else: return True
def verify_dut_sink_state_while_dut_is_playing_music(self): wait(10) if self.dut.status.get_sink_state() == SinkStates.A2DP_STREAMING: return True else: return False
def verify_dut_sink_state_while_dut_in_discoverable_state(self): for i in range(10): if self.dut.status.get_sink_state() == SinkStates.DISCOVERABLE: return True else: wait(1) return False
def cellular_off(self): if self.phone_info.phone_type == PhoneType.ANDROID: wait(4, "turn off cellular data") ret = subprocess.Popen(self.cellular_off_command, shell=True) ret.wait() if ret.returncode == 0: return True else: return False else: if self.go_to_test_screen(self.go_to_cellular_setting_screen): if self.verify_setting(self.cellular_switch_off): self.driver.appium_driver.back() return True else: if self.perform_setting(self.cellular_switch): if self.verify_setting(self.cellular_switch_off): self.driver.appium_driver.back() return True else: self.driver.appium_driver.back() return False else: self.driver.appium_driver.back() return False else: self.driver.appium_driver.back() return False
def perform_double_tap_gesture(self): if self.pause_streaming and not self.resume_streaming: self.dut.captouch.captouch_double_tap() for i in range(5): wait(5) if self.dut.status.get_sink_state() == SinkStates.CONNECTED: return True else: wait(5) return False elif not self.pause_streaming and self.resume_streaming: self.dut.captouch.captouch_double_tap() for i in range(5): wait(5) if self.dut.status.get_sink_state( ) == SinkStates.A2DP_STREAMING: return True else: wait(5) return False else: if not self.dut.status.get_sink_state( ) == SinkStates.A2DP_STREAMING: return False self.dut.captouch.captouch_double_tap() wait(5) if self.dut.status.get_sink_state() == SinkStates.CONNECTED: return True else: return False
def verify_volume_level_while_swipe_captouch_up_down( self, forward=False, back=False): wait(3) perform_up_down_gestures = SwipeCapTouchUpDown(self.dut) perform_up_down_gestures.start() perform_up_down_gestures.join() return perform_up_down_gestures.get_result()
def verify_dut_sink_state_while_previous_response_was_interrupted(self): for i in range(10): if self.dut.status.get_sink_state() == SinkStates.A2DP_STREAMING: return True else: wait(1) return False
def music_resuming_after_interruption(self, wait_time=5): logger.info('start to resume music') if self.phone_info.phone_type == PhoneType.ANDROID: for i in range(30): try: WebDriverWait(self.driver.appium_driver, wait_time, 1).until( lambda x: x.find_element_by_xpath(self.pause_music_label)) except Exception as e: logger.info('Music was not resumed, try again') wait(1) else: logger.info('Music has been resumed') return True else: return False else: for i in range(30): try: ele_obj = self.driver.appium_driver.find_element_by_xpath(self.play_or_pause_music_button) if ele_obj.text == "暂停": logger.info('Music has been resumed') return True except Exception as e: logger.info('Music was not resumed, try again') wait(1) else: return False
def perform_back_gesture(self): self.dut.captouch.captouch_swipe_back() wait(3) if self.dut.status.get_sink_state() == SinkStates.A2DP_STREAMING: return True else: return False
def play_query_voice(self): self.engine.setProperty('rate', self.rate) if sys.platform == 'win32': self.engine.setProperty( "voice", r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_ZH-CN_HUIHUI_11.0" ) if sys.platform == 'darwin': self.engine.setProperty( "voice", r"com.apple.speech.synthesis.voice.ting-ting") wait(1) self.engine.connect('started-utterance', self.start_voice_query) self.engine.connect('finished-utterance', self.finish_voice_query) self.engine.say(self.query_words, "xiaowei vpa query") self.engine.startLoop() # self.engine.runAndWait() self.engine.disconnect({ "topic": 'started-utterance', "cb": self.start_voice_query }) self.engine.disconnect({ "topic": 'finished-utterance', "cb": self.finish_voice_query })
def perform_down_gesture(self): for i in range(20): self.dut.captouch.captouch_swipe_down() if self.dut.status.get_volume() == self.min_volume: return True else: wait(0.5) return False
def verify_dut_sink_state_while_swipe_captouch_forward_back( self, forward, back): wait(3) perform_forward_back_gestures = SwipeCapTouchForwardBack( self.dut, forward, back) perform_forward_back_gestures.start() perform_forward_back_gestures.join() return perform_forward_back_gestures.get_result()
def close_pop_window(self, wait_time=5): wait(5, 'If there is a pop window, close it') try: WebDriverWait(self.driver.appium_driver, wait_time, 1).until( lambda x: x.find_element_by_xpath(self.close_membership_application_button)) except Exception as e: return True else: logger.info('Succeed to close pop windows') return self._verify_and_click_element(self.close_membership_application_button)
def check_qq_music_pause_state(self): wait(1) active_app = self.phone.qqmusic.activate_app() click_no_reminder_button = self.phone.qqmusic.no_reminder_for_music_interruption( ) pause_music = self.phone.qqmusic.pause_music() if active_app and click_no_reminder_button and pause_music: if self.dut.status.get_sink_state() == SinkStates.A2DP_STREAMING: logger.info( "QQ music has been paused, streaming is come from VPA response" ) return True
def perform_setting(self, perform_setting_xpath): try: logger.info("Perform the required setting") wait(1) self.driver.appium_driver.find_element_by_xpath( perform_setting_xpath).click() except Exception as e: logger.error("Unable to do the required setting") return False else: logger.info("Complete the required setting") return True
def activate_app(self): logger.info('Xiaowei will be brought to foreground') try: self.driver.appium_driver.activate_app(self.package_name) except Exception as e: logger.error(e) logger.info('Xiaowei cannot be brought to foreground') return False else: logger.info('Xiaowei has been brought to foreground successfully') wait(5) return True
def lock_screen(self, condition, lock_time): logger.info('Screen will be locked') try: self.driver.appium_driver.lock(lock_time) except Exception as e: logger.error(e) condition.wait() self.unlock_screen() wait(2) self.swip_up(n=2) wait(2) self.unlock_with_password() condition.notify()
def test_vpa(cls, dut, query_words, button=Buttons.VPA, hold_seconds=5, how_many_times=1, phone=None, turn_off_network=False, turn_off_bluetooth=False, close_xiaowei=False): wait(3) press_vpa_button = VPAProcess(dut, button, hold_seconds, how_many_times) if phone and turn_off_network: if not phone.launch_application(PhoneAppType.SETTINGS): return False if not phone.settings.cellular_off(): return False phone_setting = PhoneSetting(phone, setting="network") phone_setting.start() wait(5, "network will be turned off") press_vpa_button.start() play_vpa_voice = GenerateVoiceToQuery(query_words) play_vpa_voice.play_query_voice() phone_setting.join() if not phone_setting.get_result(): return False elif phone and turn_off_bluetooth: if not phone.launch_application(PhoneAppType.SETTINGS): return False phone_setting = PhoneSetting(phone, setting="bluetooth") phone_setting.start() wait(8, "bluetooth will be turned off") press_vpa_button.start() play_vpa_voice = GenerateVoiceToQuery(query_words) play_vpa_voice.play_query_voice() phone_setting.join() if not phone_setting.get_result(): return False elif phone and close_xiaowei: press_vpa_button.start() play_vpa_voice = GenerateVoiceToQuery(query_words) play_vpa_voice.play_query_voice() wait(2) if not phone.xiaowei.terminate_app(): return False else: press_vpa_button.start() play_vpa_voice = GenerateVoiceToQuery(query_words) play_vpa_voice.play_query_voice() press_vpa_button.join() cls.verify_vpa_status = VerifyVPAStatus(dut, phone) return True
def verify_dut_sink_state(self, test_native_vpa=False): count = 0 ss_a2dp_streaming = False ss_active_call_sco = False ss_no_call_sco = False ss_connected = False while count < 10: # If sink state of dut has not changed to A2DP_STREAMING or ACTIVE_CALL_SCO within 10s after releasing VPA button, the test fail logger.info("Check if the ss has changed to A2DP_STREAMING") if self.dut.status.get_sink_state() == SinkStates.A2DP_STREAMING: logger.info("waiting for response to play") ss_a2dp_streaming = True break elif self.dut.status.get_sink_state( ) == SinkStates.ACTIVE_CALL_SCO: logger.info("waiting for response to play") ss_active_call_sco = True break elif self.dut.status.get_sink_state( ) == SinkStates.DEVICE_NO_CALL_SCO: logger.info("waiting for response to play") ss_no_call_sco = True break else: wait(1) count += 1 if not (ss_a2dp_streaming or ss_active_call_sco or ss_no_call_sco): return False else: # If sink state of dut has not changed to CONNECTED within 250s after playing a2dp stream, the test fail count = 0 while count < 250: logger.info("Check if the ss has changed to CONNECTED") if self.dut.status.get_sink_state() == SinkStates.CONNECTED: logger.info("VPA response is over") ss_connected = True break else: wait(1) count += 1 if ss_a2dp_streaming and ss_connected: return True elif test_native_vpa and ss_active_call_sco and ss_connected: return True else: return False
def verify_dut_sink_state_and_check_a2dp_source(self): wait(5) check_a2dp_source = CheckA2DPSource(self.dut, self.phone) check_a2dp_source.start() check_a2dp_source.join() test_result = check_a2dp_source.get_result() if test_result: resume_music = self.phone.qqmusic.music_resuming_after_interruption( ) if resume_music: if self.get_dut_sink_state() == SinkStates.A2DP_STREAMING: return True else: return False else: return False else: return test_result
def test_Retrieve_PTT_Configuration_Before_Setting_Up_VPA_01(automation_xiaowei_ux): dut = automation_xiaowei_ux[0] phone = automation_xiaowei_ux[1] current_name = dut.bluetooth.get_name() query_response_dict = XiaoweiSupport.xw_query_response_dict() query_text = random.choice(list(query_response_dict["query_weather"])) response_text = query_response_dict["query_weather"][query_text] def test_xiaowei_query(stepnum1, stepnum2): test_step(stepnum1, "Test xiaowei voice query the weather of a city", dut) XiaoweiSupport.test_vpa(dut, query_text) assert XiaoweiSupport.test_xiaowei_vpa(), "xiaowei recording or streaming failed" test_step(stepnum2, "Verify that the text of this query and response in xiaowei APP is correct or not", dut) assert phone.xiaowei.verify_query_response_text(query_text, response_text, response_with_icon=True), "xiaowei query or response failed" test_step(1, "Perform factory default", dut) assert dut.device.perform_factory_default(restore_name=True, wait_time_after_fd=5), "Failed to perform factory default" dut.manager.initialize() test_step(2, "Check PPT of native VPA", dut) assert dut.status.get_push_to_talk_vpa_status() == '2', "Failed to check PTT status of native VPA" phone.launch_application(PhoneAppType.BLUETOOTH) for device in phone.bluetooth.bt_get_pairlist(): phone.bluetooth.bt_unpair(device) # don't use Precondition.set_discoverable(dut), because Precondition.set_discoverable(dut) may power cycle dut. # For earbuds test, initialize() is needed after power cycle # dut.bluetooth.set_discoverable() just send a BMAP to dut dut.bluetooth.set_discoverable() phone.bluetooth.bt_radio(enable='off') phone.bluetooth.bt_radio(enable='on') assert phone.bluetooth.bt_connect(current_name), "Failed to reconnect dut via bluetooth" test_step(3, "Switch to xiaowei APP", dut) assert phone.launch_application(PhoneAppType.XIAOWEI), "Failed to switch to Xiaowei" test_step(4, "Verify if xiaowei connect to dut", dut) assert phone.xiaowei.insure_device_connection(), "Failed to connect dut via xiaowei" test_step(5, "Verify if xiaowei connect to dut", dut) #because product change VPA slowly for _ in range(5): wait(1) if dut.status.get_push_to_talk_vpa_status() == '3': break else: assert False, "Failed to check PTT status of xiaowei VPA" test_xiaowei_query(6, 7) phone.xiaowei.swip_down(n=8)
def unlock_with_password(self): if self.phone_info.phone_type == PhoneType.IOS: self.driver.appium_driver.find_element_by_xpath(self.key2).click() wait(0.5) self.driver.appium_driver.find_element_by_xpath(self.key6).click() wait(0.5) self.driver.appium_driver.find_element_by_xpath(self.key7).click() wait(0.5) self.driver.appium_driver.find_element_by_xpath(self.key3).click() wait(0.5) else: pass
def airplane_on(self): if self.phone_info.phone_type == PhoneType.ANDROID: wait(4, "turn on airplane mode") ret = subprocess.Popen(self.airplane_on_command, shell=True) ret.wait() if ret.returncode == 0: return True else: return False else: if self.verify_setting(self.airplane_mode_switch_on): return True else: if self.perform_setting(self.airplane_mode_switch): if self.verify_setting(self.airplane_mode_switch_on): return True else: return False else: return False
def test_Xiaowei_Hibernation_Cycle_01(automation_xiaowei_connect): cycle_time = 4 #duration, unit - h dut = automation_xiaowei_connect[0] current_name = dut.bluetooth.get_name() phone = automation_xiaowei_connect[1] query_response_dict = XiaoweiSupport.xw_query_response_dict() query_text = random.choice(list(query_response_dict["query_weekday"])) response_text = query_response_dict["query_weekday"][query_text] assert phone.xiaowei.verify_device_icon(), "Xiaowei connection fail" @retry(stop_max_attempt_number=3, wait_fixed=2000) def test_xiaowei_query(stepnum1, stepnum2): test_step(stepnum1, "Test xiaowei voice query the query_weather", dut) XiaoweiSupport.test_vpa(dut, query_text) assert XiaoweiSupport.test_xiaowei_vpa(), "xiaowei recording or streaming failed" test_step(stepnum2, "Verify that the text of this query and response in xiaowei APP is correct or not", dut) assert phone.xiaowei.verify_query_response_text(query_text, response_text), "xiaowei query or response failed" test_step(1, "Set dut auto off", dut) assert dut.device.enable_auto_off() == '5', "Fail to set auto off timer as 5" base_t = time.time() current_t = time.time() while float(current_t-base_t) <= float(cycle_time*3600): test_step(2, "Check if dut power off in 10 minutes", dut) for i in [300, 60, 60, 60, 60, 60, 60]: wait(i) if dut.status.get_sink_state() == SinkStates.STANDBY: break else: assert False, "Dut didn't power off in 10 minutes" test_step(3, "Power on dut", dut) assert dut.key.press_power_on(), "Fail to power on dut" wait(3) test_step(4, "Dut connect to phone and xiaowei", dut) assert phone.launch_application(PhoneAppType.BLUETOOTH), "Failed to switch to bluetooth settings" if not phone.bluetooth.bt_is_connected_to(current_name): assert phone.bluetooth.connect_paired_device(current_name), "Failed to dut via bluetooth" assert phone.launch_application(PhoneAppType.XIAOWEI), "Failed to switch to Xiaowei" test_xiaowei_query(5, 6) current_t = time.time() phone.xiaowei.swip_down(n=8)
def test_Xiaowei_VPA_Button_Stress_01(automation_xiaowei_connect): dut = automation_xiaowei_connect[0] phone = automation_xiaowei_connect[1] assert phone.xiaowei.verify_device_icon(), "Xiaowei connection fail" cycle = 40 for i in range(cycle): press_time = random.choice([0.35, 1, 2, 3, 5, 8, 13, 21]) logger.info("VPA button stress for %d times, %d" % (cycle, i + 1)) test_step(1, "Power VPA button for %d second" % press_time, dut) dut.key.press_and_release(keys=Buttons.VPA, press_duration_sec=press_time) wait(2) query_response_dict = XiaoweiSupport.xw_query_response_dict() query_text = random.choice(list(query_response_dict["query_weekday"])) response_text = query_response_dict["query_weekday"][query_text] test_step(2, "Test xiaowei voice query the query_weather", dut) XiaoweiSupport.test_vpa(dut, query_text) assert XiaoweiSupport.test_xiaowei_vpa(), "xiaowei recording or streaming failed" test_step(3, "Verify that the text of this query and response in xiaowei APP is correct or not", dut) assert phone.xiaowei.verify_query_response_text(query_text, response_text), "xiaowei query or response failed" phone.xiaowei.swip_down(n=8)
def test_Xiaowei_Bluetooth_Disable_Cycle_01(automation_xiaowei_connect): dut = automation_xiaowei_connect[0] current_name = dut.bluetooth.get_name() phone = automation_xiaowei_connect[1] assert phone.xiaowei.verify_device_icon(), "Xiaowei connection fail" cycle = 20 for i in range(cycle): logger.info("Test Bluetooth disable and enable cycle for %d times, %d" % (cycle, i + 1)) test_step(1, "Switch to bluetooth settings", dut) assert phone.launch_application(PhoneAppType.BLUETOOTH), "Failed to switch to bluetooth settings" test_step(2, "Disable bluetooth on phone", dut) assert phone.bluetooth.bt_radio(enable='off'), "Failed to disable bluetooth" test_step(3, "Enable bluetooth on phone", dut) assert phone.bluetooth.bt_radio(enable='on'), "Failed to enable bluetooth" # iPhone will not connect with blutooth device after disable/enable bluetooth wait(3) if not phone.bluetooth.bt_is_connected_to(current_name): assert phone.bluetooth.connect_paired_device(current_name), "Failed to dut via bluetooth" wait(0.5) ###iap issue workaround test_step(4, "Switch to xiaowei APP", dut) assert phone.launch_application(PhoneAppType.XIAOWEI), "Failed to switch to Xiaowei" test_step(5, "Verify if xiaowei connect to dut", dut) assert phone.xiaowei.verify_device_icon(), "Fail to connect with dut"
def verify_query_no_response_text(self, query_text): wait(2) logger.info('Get text of this query %s ...' % query_text) if self.phone_info.phone_type == PhoneType.ANDROID: xw_query_in_current_page = self.driver.appium_driver.find_elements_by_xpath( self.get_query_response_text) count = 0 xw_last_query = xw_query_in_current_page[-1].text if xw_last_query == query_text: return xw_last_query else: for xiaowei_item in xw_query_in_current_page: if xiaowei_item.text.find("你好,我是小微") >= 0: try: logger.info( "query text in xiaowei : %s" % xw_query_in_current_page[count + 1].text) if count + 1 == len(xw_query_in_current_page): return "录音失败" # elif len(xw_query_in_current_page) > count + 2: # return "录音失败" else: return xw_query_in_current_page[count + 1].text except Exception as e: return "录音失败" else: count += 1 else: try: xw_query_in_current_page = self.driver.appium_driver.find_element_by_xpath( self.get_query_text) except Exception as e: return "录音失败" else: xw_last_query = xw_query_in_current_page.text return xw_last_query