def test_active_state(self): self.instruct("About to test active state. Please click OK and then watch the screen") self.marionette.execute_script(""" window.wrappedJSObject.testActiveObserver = { time : 5, onidle : function() { window.navigator.mozPower.screenBrightness = 0.1; window.wrappedJSObject.rcvd_idle = true; }, onactive : function() { window.navigator.mozPower.screenBrightness = 0.5; window.wrappedJSObject.rcvd_active = true; } }; navigator.addIdleObserver(window.wrappedJSObject.testActiveObserver); """) wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_idle;")) except: self.fail("Failed to attain idle state") self.confirm("Did you notice decrease in brightness?") self.instruct("Touch on the screen to wake up the device") wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_active;")) except: self.fail("Failed to attain active state") self.confirm("Did you notice increase in brightness?")
def answer_call(self, incoming=True): # answer incoming call via the webapi; have user answer outgoing call on target self.marionette.execute_async_script(""" let incoming = arguments[0]; if (incoming) { var call_to_answer = window.wrappedJSObject.incoming_call; } else { var call_to_answer = window.wrappedJSObject.outgoing_call; }; window.wrappedJSObject.received_statechange = false; call_to_answer.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "connected") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.connected_call_ok = false; call_to_answer.onconnected = function onconnected(event) { console.log("Received 'onconnected' call event."); if (event.call.state == "connected") { window.wrappedJSObject.active_call = window.navigator.mozTelephony.active; window.wrappedJSObject.returnable_active_call = { state: window.navigator.mozTelephony.active.state, number: window.navigator.mozTelephony.active.number }; window.wrappedJSObject.connected_call_ok = true; }; }; // answer incoming call via webapi; outgoing will be by user interaction if (incoming) { call_to_answer.answer(); }; marionetteScriptFinished(1); """, script_args=[incoming]) # answer outgoing call via user answering on target if not incoming: self.instruct( "Please answer the call on the target phone, then click 'OK'") # should have received both events associated with answering a call wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.connected_call_ok")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) except: self.fail("Failed to answer call") # append new call to the active call list self.active_call_list.append( self.marionette.execute_script( "return window.wrappedJSObject.returnable_active_call"))
def test_telephony_outgoing_busy(self): self.instruct("Make a call to second non firefox OS phone from third non firefox " "OS phone, answer the call on second phone and press OK") # keep a short delay before making an outgoing call to second phone time.sleep(2) # use the webapi to make an outgoing call to user-specified number self.user_guided_outgoing_call() # verify one outgoing call self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 1, "There should be 1 call") self.assertEqual(self.calls['0'], self.outgoing_call) # should have received busy event associated with an outgoing call wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_busy")) except: self.fail("Busy event is not found, but should have been, since the outgoing call " "is initiated to busy line") # keep call ringing for a while time.sleep(1) # disconnect the outgoing call self.hangup_call(call_type="Outgoing") self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 0, "There should be 0 calls")
def set_geolocation_enabled(self, enable): # turn on geolocation via the device settings self.marionette.execute_async_script(""" var enable = arguments[0]; window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; if (enable) { console.log("Enabling geolocation via settings"); } else { console.log("Disabling geolocation via settings"); } var lock = window.navigator.mozSettings.createLock(); var result = lock.set({ 'geolocation.enabled': enable }); result.onsuccess = function() { console.log("Success changing geolocation.enabled setting"); window.wrappedJSObject.rcvd_success = true; }; result.onerror = function(error) { console.log("Failed to change geolocation.enabled setting " + error); window.wrappedJSObject.rcvd_error = true; }; marionetteScriptFinished(1); """, script_args=[enable]) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error;"): self.fail("Error received while changing the geolocation enabled setting") else: self.fail("Failed to change the geolocation.enabled setting")
def resume_held_call(self): self.marionette.execute_async_script(""" let active = window.wrappedJSObject.active_call; window.wrappedJSObject.received_statechange = false; active.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "resuming") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.onresuming_call_ok = false; active.onresuming = function onresuming(event) { console.log("Received 'onresuming' call event."); if (event.call.state == "resuming") { window.wrappedJSObject.onresuming_call_ok = true; }; }; active.resume(); marionetteScriptFinished(1); """) # should have received event associated with a resumed call wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.onresuming_call_ok")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) except: # failed to resume self.fail("Failed to resume the held call")
def assert_message_sent(self): """ After sending an SMS/MMS, call this method to wait for the message to be sent. Verify that a mobile message was sent by checking if the expected events were triggered. Once verified, set the out_msg attribute to point to the message that has been sent. """ wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda m: self.marionette.execute_script("return window.wrappedJSObject.rcvd_req_success")) except errors.TimeoutException: # msg wasn't sent; either the api is broken or mobile network signal is insufficient self.fail( "Failed to send message. The API is broken -or- " "perhaps there is no mobile network signal. Please try again" ) # verify the remaining msg send events rcvd_failed = self.marionette.execute_script("return window.wrappedJSObject.rcvd_on_failed") self.assertFalse(rcvd_failed, "Failed to send message; received mozMobileMessage.onfailed event") rcvd_sending = self.marionette.execute_script("return window.wrappedJSObject.rcvd_on_sending") self.assertTrue(rcvd_sending, "Failed to send message; mozMobileMessage.onsending event not received") rcvd_sent = self.marionette.execute_script("return window.wrappedJSObject.rcvd_on_sent") self.assertTrue(rcvd_sent, "Failed to send message; mozMobileMessage.onsent event not received") # get message event self.out_msg = self.marionette.execute_script("return window.wrappedJSObject.out_msg")
def create_notification(self, text): self.marionette.execute_async_script(""" window.wrappedJSObject.rcvd_onshow = false; var text = arguments[0]; console.log("Creating new notification"); var notification = new Notification(text); // setup callback notification.onshow = function() { console.log("Received Notification.onshow event"); window.wrappedJSObject.rcvd_onshow = true; } marionetteScriptFinished(1); """, script_args=[text]) # wait for notification to be displayed wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.rcvd_onshow")) except: self.fail("Did not receive the Notification.onshow event")
def is_geolocation_enabled(self): self.marionette.execute_async_script(""" window.wrappedJSObject.geo_enabled = null; window.wrappedJSObject.get_success = false; var lock = navigator.mozSettings.createLock(); var setting = lock.get('geolocation.enabled'); setting.onsuccess = function () { console.log('geolocation.enabled: ' + setting.result); window.wrappedJSObject.get_success = true; window.wrappedJSObject.geo_enabled = setting.result["geolocation.enabled"]; } setting.onerror = function () { console.log('An error occured: ' + setting.error); } marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.get_success")) except: self.fail("Failed to get the geolocation.enabled setting") return self.marionette.execute_script( "return window.wrappedJSObject.geo_enabled")
def resume_held_call(self): self.marionette.execute_async_script(""" let active = window.wrappedJSObject.active_call; window.wrappedJSObject.received_statechange = false; active.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "resuming") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.onresuming_call_ok = false; active.onresuming = function onresuming(event) { console.log("Received 'onresuming' call event."); if (event.call.state == "resuming") { window.wrappedJSObject.onresuming_call_ok = true; }; }; active.resume(); marionetteScriptFinished(1); """) # should have received event associated with a resumed call wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.onresuming_call_ok")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) except: # failed to resume self.fail("Failed to resume the held call")
def wait_for_antenna_change(self): # wait for radio to change state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.antenna_change")) except: self.fail("Failed to receive mozFMRadio.onantennaavailablechange event")
def set_bt_enabled(self, enable): self.get_default_bt_adapter() if enable: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.enable(); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.disable(); marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: if enable: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.state == 'enabled';")) else: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.state == 'disabled';")) except: if enable: self.fail("Failed to enable bluetooth") else: self.fail("Failed to disable bluetooth")
def set_bt_discoverable_mode(self, set_discoverable): self.set_bt_enabled(True) if set_discoverable: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.setDiscoverable(true); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.disable(false); marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: if set_discoverable: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.discoverable == true;")) else: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.discoverable == false;")) except: if set_discoverable: self.fail("Failed to enable bluetooth discoverable") else: self.fail("Failed to disable bluetooth discoverable")
def set_bt_enabled(self, enable): self.get_default_bt_adapter() if enable: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.enable(); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.disable(); marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: if enable: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.state == 'enabled';" )) else: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.state == 'disabled';" )) except: if enable: self.fail("Failed to enable bluetooth") else: self.fail("Failed to disable bluetooth")
def hold_active_call(self, user_initiate_hold=True): self.marionette.execute_async_script(""" let active = window.wrappedJSObject.active_call; var user_initiate_hold = arguments[0]; window.wrappedJSObject.received_statechange = false; active.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "held") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.onheld_call_ok = false; active.onheld = function ondisconnected(event) { console.log("Received 'onheld' call event."); if (event.call.state == "held") { window.wrappedJSObject.onheld_call_ok = true; }; }; if (user_initiate_hold) { active.hold(); } marionetteScriptFinished(1); """, script_args=[user_initiate_hold]) if user_initiate_hold == True: # should have received both events associated with a call on hold wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.onheld_call_ok")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) except: # failed to hold self.fail("Failed to put call on hold initiated by user")
def set_bt_discoverable_mode(self, set_discoverable): self.set_bt_enabled(True) if set_discoverable: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.setDiscoverable(true); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.disable(false); marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: if set_discoverable: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.discoverable == true;" )) else: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.discoverable == false;" )) except: if set_discoverable: self.fail("Failed to enable bluetooth discoverable") else: self.fail("Failed to disable bluetooth discoverable")
def test_idle_state(self): self.instruct( "About to test idle state. Please click OK and then watch the screen, but do not touch the screen" ) self.marionette.execute_script(""" window.wrappedJSObject.testIdleObserver = { time : 5, onidle : function() { window.navigator.mozPower.screenBrightness = 0.1; window.wrappedJSObject.rcvd_idle = true; } }; navigator.addIdleObserver(window.wrappedJSObject.testIdleObserver); """) #wait for device to go idle wait = Wait(self.marionette, timeout=15, interval=0.5) try: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.rcvd_idle;")) except: self.fail("Failed to attain idle state") self.confirm("Did you notice decrease in brightness?")
def test_telephony_outgoing_busy(self): self.instruct( "Make a call to second non firefox OS phone from third non firefox " "OS phone, answer the call on second phone and press OK") # keep a short delay before making an outgoing call to second phone time.sleep(2) # use the webapi to make an outgoing call to user-specified number self.user_guided_outgoing_call() # verify one outgoing call self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 1, "There should be 1 call") self.assertEqual(self.calls['0'], self.outgoing_call) # should have received busy event associated with an outgoing call wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_busy")) except: self.fail( "Busy event is not found, but should have been, since the outgoing call " "is initiated to busy line") # keep call ringing for a while time.sleep(1) # disconnect the outgoing call self.hangup_call(call_type="Outgoing") self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 0, "There should be 0 calls")
def wait_for_antenna_change(self): # wait for radio to change state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.antenna_change")) except: self.fail( "Failed to receive mozFMRadio.onantennaavailablechange event")
def set_wifi_enabled(self, enable): self.marionette.execute_async_script(""" var enable = arguments[0]; window.wrappedJSObject.rcvd_enabled_event = false; window.wrappedJSObject.rcvd_disabled_event = false; window.wrappedJSObject.rcvd_error = false; var mozWifi = window.navigator.mozWifiManager; mozWifi.onenabled = function() { console.log("Received mozWifiManager.onenabled event"); window.wrappedJSObject.rcvd_enabled_event = true; }; mozWifi.ondisabled = function() { console.log("Received mozWifiManager.ondisabled event"); window.wrappedJSObject.rcvd_disabled_event = true; }; if (enable) { console.log("Turning on Wifi via settings"); } else { console.log("Turning off Wifi via settings"); } var lock = window.navigator.mozSettings.createLock(); var result = lock.set({ 'wifi.enabled': enable }); result.onerror = function() { if (enable) { console.log("Failed to changed Wifi setting to ON"); } else { console.log("Failed to changed Wifi setting to OFF"); } window.wrappedJSObject.rcvd_error = true; }; marionetteScriptFinished(1); """, script_args=[enable]) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: if enable: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_enabled_event;")) else: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_disabled_event;")) except: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error;"): self.fail("Error received while changing the wifi enabled setting") else: if enable: self.fail("Failed to enable wifi via mozSettings") else: self.fail("Failed to disable wifi via mozSettings")
def answer_call(self, incoming=True): # answer incoming call via the webapi; have user answer outgoing call on target self.marionette.execute_async_script(""" let incoming = arguments[0]; if (incoming) { var call_to_answer = window.wrappedJSObject.incoming_call; } else { var call_to_answer = window.wrappedJSObject.outgoing_call; }; window.wrappedJSObject.received_statechange = false; call_to_answer.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "connected") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.connected_call_ok = false; call_to_answer.onconnected = function onconnected(event) { console.log("Received 'onconnected' call event."); if (event.call.state == "connected") { window.wrappedJSObject.active_call = window.navigator.mozTelephony.active; window.wrappedJSObject.returnable_active_call = { state: window.navigator.mozTelephony.active.state, number: window.navigator.mozTelephony.active.number }; window.wrappedJSObject.connected_call_ok = true; }; }; // answer incoming call via webapi; outgoing will be by user interaction if (incoming) { call_to_answer.answer(); }; marionetteScriptFinished(1); """, script_args=[incoming]) # answer outgoing call via user answering on target if not incoming: self.instruct("Please answer the call on the target phone, then click 'OK'") # should have received both events associated with answering a call wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.connected_call_ok")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) except: self.fail("Failed to answer call") # append new call to the active call list self.active_call_list.append(self.marionette.execute_script("return window.wrappedJSObject.returnable_active_call"))
def bt_discovery(self, set_discovering): self.set_bt_enabled(True) if set_discovering: self.marionette.execute_async_script(""" window.wrappedJSObject.found_device_count = 0; var discoveryHandle; window.wrappedJSObject.bt_adapter.startDiscovery().then ( function onResolve(handle) { console.log("Resolved with discoveryHandle"); // Keep reference to handle in order to listen to ondevicefound event handler discoveryHandle = handle; discoveryHandle.ondevicefound = function onDeviceFound(evt) { var device = evt.device; console.log("Discovered remote device. Address:", device.address); window.wrappedJSObject.found_device_count++; }; }, function onReject(aReason) { console.log("Rejected with this reason: " + aReason); }); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.stopDiscovery().then ( function onResolve() { console.log("Resolved with void value"); }, function onReject(aReason) { console.log("Rejected with this reason: " + aReason); }); marionetteScriptFinished(1); """) # wait for request success wait = Wait(self.marionette, timeout=30, interval=0.5) try: if set_discovering: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.discovering == true;" )) else: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.bt_adapter.discovering == false;" )) except: if set_discovering: self.fail("Failed to enable bluetooth discovering") else: self.fail("Failed to disable bluetooth discovering")
def setup_incoming_call(self): self.marionette.execute_script(self.returnable_calls) # listen for and answer incoming call self.marionette.execute_async_script(""" var telephony = window.navigator.mozTelephony; window.wrappedJSObject.received_incoming = false; telephony.onincoming = function onincoming(event) { console.log("Received 'incoming' call event."); window.wrappedJSObject.received_incoming = true; window.wrappedJSObject.incoming_call = event.call; window.wrappedJSObject.returnable_incoming_call = { number: event.call.number, state: event.call.state }; window.wrappedJSObject.calls = telephony.calls; }; window.wrappedJSObject.received_callschanged = false; telephony.oncallschanged = function oncallschanged(event) { console.log("Received Telephony 'oncallschanged' event."); window.wrappedJSObject.received_callschanged = true; }; window.wrappedJSObject.received_ready = false; telephony.ready.then( function() { console.log("Telephony got ready"); window.wrappedJSObject.received_ready = true; }, function() { console.log("Telephony not ready"); window.wrappedJSObject.received_ready = false; } ); marionetteScriptFinished(1); """) wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_ready")) except: self.fail( "Telephony.oncallschanged event not found, but should have been " "since initiated incoming call to firefox OS device")
def bt_discovery(self, set_discovering): self.set_bt_enabled(True) if set_discovering: self.marionette.execute_async_script(""" window.wrappedJSObject.found_device_count = 0; var discoveryHandle; window.wrappedJSObject.bt_adapter.startDiscovery().then ( function onResolve(handle) { console.log("Resolved with discoveryHandle"); // Keep reference to handle in order to listen to ondevicefound event handler discoveryHandle = handle; discoveryHandle.ondevicefound = function onDeviceFound(evt) { var device = evt.device; console.log("Discovered remote device. Address:", device.address); window.wrappedJSObject.found_device_count++; }; }, function onReject(aReason) { console.log("Rejected with this reason: " + aReason); }); marionetteScriptFinished(1); """) else: self.marionette.execute_async_script(""" window.wrappedJSObject.bt_adapter.stopDiscovery().then ( function onResolve() { console.log("Resolved with void value"); }, function onReject(aReason) { console.log("Rejected with this reason: " + aReason); }); marionetteScriptFinished(1); """) # wait for request success wait = Wait(self.marionette, timeout=30, interval=0.5) try: if set_discovering: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.discovering == true;")) else: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.bt_adapter.discovering == false;")) except: if set_discovering: self.fail("Failed to enable bluetooth discovering") else: self.fail("Failed to disable bluetooth discovering")
def setup_incoming_call(self): self.marionette.execute_script(self.returnable_calls) # listen for and answer incoming call self.marionette.execute_async_script(""" var telephony = window.navigator.mozTelephony; window.wrappedJSObject.received_incoming = false; telephony.onincoming = function onincoming(event) { console.log("Received 'incoming' call event."); window.wrappedJSObject.received_incoming = true; window.wrappedJSObject.incoming_call = event.call; window.wrappedJSObject.returnable_incoming_call = { number: event.call.number, state: event.call.state }; window.wrappedJSObject.calls = telephony.calls; }; window.wrappedJSObject.received_callschanged = false; telephony.oncallschanged = function oncallschanged(event) { console.log("Received Telephony 'oncallschanged' event."); window.wrappedJSObject.received_callschanged = true; }; window.wrappedJSObject.received_ready = false; telephony.ready.then( function() { console.log("Telephony got ready"); window.wrappedJSObject.received_ready = true; }, function() { console.log("Telephony not ready"); window.wrappedJSObject.received_ready = false; } ); marionetteScriptFinished(1); """) wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_ready")) except: self.fail("Telephony.oncallschanged event not found, but should have been " "since initiated incoming call to firefox OS device")
def mark_message_status(self, msg_id, is_read=False): self.marionette.execute_async_script( """ var msg_id = arguments[0]; var is_read = arguments[1]; var requestRet = null; var mm = window.navigator.mozMobileMessage; // Bug 952875 mm.getThreads(); requestRet = mm.markMessageRead(msg_id, is_read); window.wrappedJSObject.rcvd_req_success_read = false; window.wrappedJSObject.rcvd_req_success_unread = false; requestRet.onsuccess = function(event) { log("Received 'onsuccess' event."); if (event.target.result) { window.wrappedJSObject.rcvd_req_success_read = true; } else { window.wrappedJSObject.rcvd_req_success_unread = true; log("request returned false for manager.markMessageRead"); } } requestRet.onerror = function() { log("Failed to mark message read status, received error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id, is_read], ) wait = Wait(self.marionette, timeout=15, interval=0.5) try: if is_read is True: wait.until( lambda m: self.marionette.execute_script("return window.wrappedJSObject.rcvd_req_success_read") ) else: wait.until( lambda m: self.marionette.execute_script("return window.wrappedJSObject.rcvd_req_success_unread") ) except errors.TimeoutException: # msg read status wasn't marked self.fail("Failed to update the read status of message.")
def get_current_position(self): self.marionette.execute_async_script(""" window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; window.wrappedJSObject.position = null; var mozGeo = window.navigator.geolocation; function success(position) { console.log("geolocation.getCurrentPosition success"); window.wrappedJSObject.position = position; window.wrappedJSObject.rcvd_success = true; } function error(error) { console.log("Error " + error.code + " when requesting location"); window.wrappedJSObject.rcvd_error = true; } console.log("Getting current position"); mozGeo.getCurrentPosition(success, error); marionetteScriptFinished(1); """) # ask user to accept and dismiss the default gaia app location share prompt self.instruct( "On the Firefox OS device, if a location request dialog is displayed, please " "click the 'Share' button. If there is no dialog on the device, just continue." ) # wait for the position request to finish wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script( "return window.wrappedJSObject.rcvd_error"): self.fail("geolocation.getCurrentPosition returned error") else: self.fail( "Failed to get position; either geolocation is broken -or- WiFi is not connected" ) position = self.marionette.execute_script( "return window.wrappedJSObject.position") self.assertIsNotNone(position, "mozBluetooth.getCurrentPosition returned none") return position
def mark_message_status(self, msg_id, is_read=False): self.marionette.execute_async_script(""" var msg_id = arguments[0]; var is_read = arguments[1]; var requestRet = null; var mm = window.navigator.mozMobileMessage; // Bug 952875 mm.getThreads(); requestRet = mm.markMessageRead(msg_id, is_read); window.wrappedJSObject.rcvd_req_success_read = false; window.wrappedJSObject.rcvd_req_success_unread = false; requestRet.onsuccess = function(event) { log("Received 'onsuccess' event."); if (event.target.result) { window.wrappedJSObject.rcvd_req_success_read = true; } else { window.wrappedJSObject.rcvd_req_success_unread = true; log("request returned false for manager.markMessageRead"); } } requestRet.onerror = function() { log("Failed to mark message read status, received error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id, is_read]) wait = Wait(self.marionette, timeout=15, interval=0.5) try: if is_read is True: wait.until(lambda m: self.marionette.execute_script( "return window.wrappedJSObject.rcvd_req_success_read")) else: wait.until(lambda m: self.marionette.execute_script( "return window.wrappedJSObject.rcvd_req_success_unread")) except errors.TimeoutException: # msg read status wasn't marked self.fail("Failed to update the read status of message.")
def change_radio_state(self, turning_on): # turn on or off radio and verify request self.marionette.execute_async_script(""" var turning_on = arguments[0]; var fm = window.navigator.mozFMRadio; window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; // turn on or off accordingly if (turning_on) { var request = fm.enable(99.9); } else { var request = fm.disable(); }; // verify request request.onsuccess = function() { window.wrappedJSObject.rcvd_success = true; }; request.onerror = function() { window.wrappedJSObject.rcvd_error = true; }; marionetteScriptFinished(1); """, script_args=[turning_on]) # wait for radio to change state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script( "return window.wrappedJSObject.rcvd_error"): if turning_on: self.fail("MozFMRadio.enable returned error") else: self.fail("MozFMRadio.disable returned error") else: if turning_on: self.fail("Failed to turn on the fm radio") else: self.fail("Failed to turn off the fm radio")
def set_geolocation_enabled(self, enable): # turn on geolocation via the device settings self.marionette.execute_async_script(""" var enable = arguments[0]; window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; if (enable) { console.log("Enabling geolocation via settings"); } else { console.log("Disabling geolocation via settings"); } var lock = window.navigator.mozSettings.createLock(); var result = lock.set({ 'geolocation.enabled': enable }); result.onsuccess = function() { console.log("Success changing geolocation.enabled setting"); window.wrappedJSObject.rcvd_success = true; }; result.onerror = function(error) { console.log("Failed to change geolocation.enabled setting " + error); window.wrappedJSObject.rcvd_error = true; }; marionetteScriptFinished(1); """, script_args=[enable]) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script( "return window.wrappedJSObject.rcvd_error;"): self.fail( "Error received while changing the geolocation enabled setting" ) else: self.fail("Failed to change the geolocation.enabled setting")
def get_wifi_networks(self): self.marionette.execute_async_script(""" window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; window.wrappedJSObject.wifi_networks = null; window.wrappedJSObject.error_msg = null; var mozWifi = window.navigator.mozWifiManager; console.log("Getting wifi networks"); var request = mozWifi.getNetworks(); request.onsuccess = function() { console.log("mozWifiManager.getNetworks request success"); window.wrappedJSObject.rcvd_success = true; window.wrappedJSObject.wifi_networks = this.result; }; request.onerror = function() { console.log("mozWifiManager.getNetworks request returned error: " + this.error.name); window.wrappedJSObject.rcvd_error = true; window.wrappedJSObject.error_msg = this.error.name; }; marionetteScriptFinished(1); """) # wait for wifi networks to be found wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error"): self.fail("mozWifiManager.getNetworks returned error: " + self.marionette.execute_script("return window.wrappedJSObject.error_msg")) else: self.fail("mozWifiManager.getNetworks failed") wifi_networks = self.marionette.execute_script("return window.wrappedJSObject.wifi_networks") self.assertIsNotNone(wifi_networks, "mozWifiManager.getNetowrk returned none") return wifi_networks
def assert_message_sent(self): """ After sending an SMS/MMS, call this method to wait for the message to be sent. Verify that a mobile message was sent by checking if the expected events were triggered. Once verified, set the out_msg attribute to point to the message that has been sent. """ wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda m: self.marionette.execute_script( "return window.wrappedJSObject.rcvd_req_success")) except errors.TimeoutException: # msg wasn't sent; either the api is broken or mobile network signal is insufficient self.fail( "Failed to send message. The API is broken -or- " "perhaps there is no mobile network signal. Please try again") # verify the remaining msg send events rcvd_failed = self.marionette.execute_script( "return window.wrappedJSObject.rcvd_on_failed") self.assertFalse( rcvd_failed, "Failed to send message; received mozMobileMessage.onfailed event") rcvd_sending = self.marionette.execute_script( "return window.wrappedJSObject.rcvd_on_sending") self.assertTrue( rcvd_sending, "Failed to send message; mozMobileMessage.onsending event not received" ) rcvd_sent = self.marionette.execute_script( "return window.wrappedJSObject.rcvd_on_sent") self.assertTrue( rcvd_sent, "Failed to send message; mozMobileMessage.onsent event not received" ) # get message event self.out_msg = self.marionette.execute_script( "return window.wrappedJSObject.out_msg")
def change_radio_state(self, turning_on): # turn on or off radio and verify request self.marionette.execute_async_script(""" var turning_on = arguments[0]; var fm = window.navigator.mozFMRadio; window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; // turn on or off accordingly if (turning_on) { var request = fm.enable(99.9); } else { var request = fm.disable(); }; // verify request request.onsuccess = function() { window.wrappedJSObject.rcvd_success = true; }; request.onerror = function() { window.wrappedJSObject.rcvd_error = true; }; marionetteScriptFinished(1); """, script_args=[turning_on]) # wait for radio to change state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error"): if turning_on: self.fail("MozFMRadio.enable returned error") else: self.fail("MozFMRadio.disable returned error") else: if turning_on: self.fail("Failed to turn on the fm radio") else: self.fail("Failed to turn off the fm radio")
def hold_active_call(self, user_initiate_hold=True): self.marionette.execute_async_script(""" let active = window.wrappedJSObject.active_call; var user_initiate_hold = arguments[0]; window.wrappedJSObject.received_statechange = false; active.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "held") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.onheld_call_ok = false; active.onheld = function ondisconnected(event) { console.log("Received 'onheld' call event."); if (event.call.state == "held") { window.wrappedJSObject.onheld_call_ok = true; }; }; if (user_initiate_hold) { active.hold(); } marionetteScriptFinished(1); """, script_args=[user_initiate_hold]) if user_initiate_hold == True: # should have received both events associated with a call on hold wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.onheld_call_ok")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) except: # failed to hold self.fail("Failed to put call on hold initiated by user")
def is_geolocation_enabled(self): self.marionette.execute_async_script(""" window.wrappedJSObject.geo_enabled = null; window.wrappedJSObject.get_success = false; var lock = navigator.mozSettings.createLock(); var setting = lock.get('geolocation.enabled'); setting.onsuccess = function () { console.log('geolocation.enabled: ' + setting.result); window.wrappedJSObject.get_success = true; window.wrappedJSObject.geo_enabled = setting.result["geolocation.enabled"]; } setting.onerror = function () { console.log('An error occured: ' + setting.error); } marionetteScriptFinished(1); """) # wait for enabled/disabled event wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.get_success")) except: self.fail("Failed to get the geolocation.enabled setting") return self.marionette.execute_script("return window.wrappedJSObject.geo_enabled")
def create_notification(self, text): self.marionette.execute_async_script(""" window.wrappedJSObject.rcvd_onshow = false; var text = arguments[0]; console.log("Creating new notification"); var notification = new Notification(text); // setup callback notification.onshow = function() { console.log("Received Notification.onshow event"); window.wrappedJSObject.rcvd_onshow = true; } marionetteScriptFinished(1); """, script_args=[text]) # wait for notification to be displayed wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.rcvd_onshow")) except: self.fail("Did not receive the Notification.onshow event")
def get_message(self, msg_id): """ Get the sms or mms for the given id. Return the message, or none if it doesn't exist""" self.marionette.execute_async_script( """ var mm = window.navigator.mozMobileMessage; window.wrappedJSObject.event_sms = null; window.wrappedJSObject.rcvd_event = false; // Bug 952875 mm.getThreads(); let requestRet = mm.getMessage(arguments[0]); requestRet.onsuccess = function(event) { if(event.target.result){ window.wrappedJSObject.rcvd_event = true; window.wrappedJSObject.event_sms = event.target.result; } }; requestRet.onerror = function() { window.wrappedJSObject.rcvd_event = true; log("Get message returned error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id], ) # wait for a result wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.rcvd_event")) except errors.TimeoutException: self.fail("mozMobileMessage.getMessage() failed") # return the message if it was found, otherwise none return self.marionette.execute_script("return window.wrappedJSObject.event_sms")
def get_message(self, msg_id): """ Get the sms or mms for the given id. Return the message, or none if it doesn't exist""" self.marionette.execute_async_script(""" var mm = window.navigator.mozMobileMessage; window.wrappedJSObject.event_sms = null; window.wrappedJSObject.rcvd_event = false; // Bug 952875 mm.getThreads(); let requestRet = mm.getMessage(arguments[0]); requestRet.onsuccess = function(event) { if(event.target.result){ window.wrappedJSObject.rcvd_event = true; window.wrappedJSObject.event_sms = event.target.result; } }; requestRet.onerror = function() { window.wrappedJSObject.rcvd_event = true; log("Get message returned error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id]) # wait for a result wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.rcvd_event")) except errors.TimeoutException: self.fail("mozMobileMessage.getMessage() failed") # return the message if it was found, otherwise none return self.marionette.execute_script( "return window.wrappedJSObject.event_sms")
def get_current_position(self): self.marionette.execute_async_script(""" window.wrappedJSObject.rcvd_success = false; window.wrappedJSObject.rcvd_error = false; window.wrappedJSObject.position = null; var mozGeo = window.navigator.geolocation; function success(position) { console.log("geolocation.getCurrentPosition success"); window.wrappedJSObject.position = position; window.wrappedJSObject.rcvd_success = true; } function error(error) { console.log("Error " + error.code + " when requesting location"); window.wrappedJSObject.rcvd_error = true; } console.log("Getting current position"); mozGeo.getCurrentPosition(success, error); marionetteScriptFinished(1); """) # ask user to accept and dismiss the default gaia app location share prompt self.instruct("On the Firefox OS device, if a location request dialog is displayed, please " "click the 'Share' button. If there is no dialog on the device, just continue.") # wait for the position request to finish wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.rcvd_success")) except: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error"): self.fail("geolocation.getCurrentPosition returned error") else: self.fail("Failed to get position; either geolocation is broken -or- WiFi is not connected") position = self.marionette.execute_script("return window.wrappedJSObject.position") self.assertIsNotNone(position, "mozBluetooth.getCurrentPosition returned none") return position
def delete_message(self, msg_id): self.marionette.execute_async_script(""" var mm = window.navigator.mozMobileMessage; window.wrappedJSObject.msg_deleted = false; window.wrappedJSObject.rcvd_error = false; // Bug 952875 mm.getThreads(); let requestRet = mm.delete(arguments[0]); requestRet.onsuccess = function(event) { if (event.target.result) { window.wrappedJSObject.msg_deleted = true; } else { window.wrappedJSObject.msg_deleted = false; } }; requestRet.onerror = function() { window.wrappedJSObject.rcvd_error = true; log("Delete message returned error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id]) # wait for request.onsuccess wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script( "return window.wrappedJSObject.msg_deleted")) except errors.TimeoutException: if self.marionette.execute_script( "return window.wrappedJSObject.rcvd_error;"): self.fail("Error received while deleting message") else: self.fail("Failed to delete message")
def delete_message(self, msg_id): self.marionette.execute_async_script( """ var mm = window.navigator.mozMobileMessage; window.wrappedJSObject.msg_deleted = false; window.wrappedJSObject.rcvd_error = false; // Bug 952875 mm.getThreads(); let requestRet = mm.delete(arguments[0]); requestRet.onsuccess = function(event) { if (event.target.result) { window.wrappedJSObject.msg_deleted = true; } else { window.wrappedJSObject.msg_deleted = false; } }; requestRet.onerror = function() { window.wrappedJSObject.rcvd_error = true; log("Delete message returned error: %s" % requestRet.error.name); }; marionetteScriptFinished(1); """, script_args=[msg_id], ) # wait for request.onsuccess wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda m: m.execute_script("return window.wrappedJSObject.msg_deleted")) except errors.TimeoutException: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error;"): self.fail("Error received while deleting message") else: self.fail("Failed to delete message")
def test_main_tab_scalars(self): wait = Wait(self.marionette, 10) with self.marionette.using_context(self.marionette.CONTEXT_CHROME): tab1 = self.browser.tabbar.selected_tab tab2 = self.browser.tabbar.open_tab() wait.until(lambda m: len(self.browser.tabbar.tabs) == 2) self.browser.tabbar.switch_to(tab2) tab3 = self.browser.tabbar.open_tab() wait.until(lambda m: len(self.browser.tabbar.tabs) == 3) self.browser.tabbar.switch_to(tab3) self.browser.tabbar.close_tab(tab3, force=True) wait.until(lambda m: len(self.browser.tabbar.tabs) == 2) self.browser.tabbar.close_tab(tab2, force=True) wait.until(lambda m: len(self.browser.tabbar.tabs) == 1) self.browser.tabbar.switch_to(tab1) ping = self.wait_for_ping(self.restart_browser, lambda p: p['type'] == 'main' and p['payload']['info']['reason'] == 'shutdown') assert ping['type'] == 'main' assert ping['clientId'] == self.client_id scalars = ping['payload']['processes']['parent']['scalars'] assert scalars['browser.engagement.max_concurrent_tab_count'] == 3 assert scalars['browser.engagement.tab_open_event_count'] == 2 assert scalars['browser.engagement.max_concurrent_window_count'] == 1
def hangup_call(self, call_type="Active", remote_hangup=False, active_call_selected=0): # hangup the active/incoming call, verify self.marionette.execute_async_script( """ var call_type = arguments[0]; var remote_hangup = arguments[1]; var active_call_selected = arguments[2]; window.wrappedJSObject.rcvd_error = false; if (call_type == "Incoming") { var call_to_hangup = window.wrappedJSObject.incoming_call; } else if (call_type == "Outgoing") { var call_to_hangup = window.wrappedJSObject.outgoing_call; } else { if (active_call_selected >=0 && active_call_selected < window.wrappedJSObject.calls.length) { var call_to_hangup = window.wrappedJSObject.calls[active_call_selected]; } else { window.wrappedJSObject.rcvd_error = true; marionetteScriptFinished(0); } }; window.wrappedJSObject.received_statechange = false; call_to_hangup.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "disconnected") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.disconnected_call_ok = false; call_to_hangup.ondisconnected = function ondisconnected(event) { console.log("Received 'ondisconnected' call event."); if (event.call.state == "disconnected") { window.wrappedJSObject.disconnected_call_ok = true; }; }; if (!remote_hangup) { call_to_hangup.hangUp(); } marionetteScriptFinished(1); """, script_args=[call_type, remote_hangup, active_call_selected]) if remote_hangup == False: if self.marionette.execute_script( "return window.wrappedJSObject.rcvd_error;"): self.fail("Received invalid value for active_call_selected") # should have received both events associated with a active call hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.disconnected_call_ok")) except: # failed to hangup self.fail("Failed to hangup call") else: self.instruct( "Hangup the call from secondary phone and press 'OK'") # should have received only disconnected event associated with a active call hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.disconnected_call_ok")) except: # failed to hangup self.fail("Failed to hangup call") # verify that the call disconnected from phone which is not the device under test disconnecting = self.marionette.execute_script( "return window.wrappedJSObject.disconnecting_call_ok") self.assertFalse( disconnecting, "Telephony.ondisconnecting event found, but should not have been " "since the call was terminated remotely") # should have received events associated with a state and calls change for with or without remote hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_callschanged")) except: self.fail( "Failed to receive either statechange or callschanged events") # remove the call from list if call_type == "Active": self.active_call_list.pop(active_call_selected)
def test_timeout_elapsed_rounding(self): wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0) with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 1.0 seconds"): wt.until(lambda x: x.true(), is_true=now)
class WaitUntilTest(MarionetteTestCase): def setUp(self): super(WaitUntilTest, self).setUp() self.m = MockMarionette() self.clock = TickingClock() self.wt = Wait(self.m, timeout=10, interval=1, clock=self.clock) def test_true(self): r = self.wt.until(lambda x: x.true()) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_true_within_timeout(self): r = self.wt.until(lambda x: x.true(wait=5)) self.assertTrue(r) self.assertEqual(self.clock.ticks, 4) def test_timeout(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.true(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_exception_raises_immediately(self): with self.assertRaises(TypeError): self.wt.until(lambda x: x.exception(e=TypeError)) self.assertEqual(self.clock.ticks, 0) def test_ignored_exception(self): self.wt.exceptions = (TypeError, ) with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.exception(e=TypeError)) def test_ignored_exception_wrapped_in_timeoutexception(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError)) except Exception as e: exc = e s = str(exc) self.assertIsNotNone(exc) self.assertIsInstance(exc, errors.TimeoutException) self.assertIn(", caused by {0!r}".format(TypeError), s) self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s) def test_ignored_exception_after_timeout_is_not_raised(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.exception(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_keyboard_interrupt(self): with self.assertRaises(KeyboardInterrupt): self.wt.until(lambda x: x.exception(e=KeyboardInterrupt)) def test_system_exit(self): with self.assertRaises(SystemExit): self.wt.until(lambda x: x.exception(SystemExit)) def test_true_condition_returns_immediately(self): r = self.wt.until(lambda x: x.true()) self.assertIsInstance(r, bool) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_value(self): r = self.wt.until(lambda x: "foo") self.assertEqual(r, "foo") self.assertEqual(self.clock.ticks, 0) def test_custom_predicate(self): r = self.wt.until(lambda x: x.true(wait=2), is_true=at_third_attempt) self.assertTrue(r) self.assertEqual(self.clock.ticks, 1) def test_custom_predicate_times_out(self): with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) self.assertEqual(self.clock.ticks, 2) def test_timeout_elapsed_duration(self): with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 2.0 seconds"): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) def test_timeout_elapsed_rounding(self): wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0) with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 1.0 seconds"): wt.until(lambda x: x.true(), is_true=now) def test_timeout_elapsed_interval_by_delayed_condition_return(self): def callback(mn): self.clock.sleep(11) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 11.0 seconds"): self.wt.until(callback) # With a delayed conditional return > timeout, only 1 iteration is # possible self.assertEqual(self.m.waited, 1) def test_timeout_with_delayed_condition_return(self): def callback(mn): self.clock.sleep(.5) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 10.0 seconds"): self.wt.until(callback) # With a delayed conditional return < interval, 10 iterations should be # possible self.assertEqual(self.m.waited, 10) def test_timeout_interval_shorter_than_delayed_condition_return(self): def callback(mn): self.clock.sleep(2) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 10.0 seconds"): self.wt.until(callback) # With a delayed return of the conditional which takes twice that long than the interval, # half of the iterations should be possible self.assertEqual(self.m.waited, 5) def test_message(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="hooba") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds with message: hooba, caused by", result) def test_no_message(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds, caused by", result) def test_message_has_none_as_its_value(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(False, None, None) except errors.TimeoutException as e: exc = e result = str(exc) self.assertNotIn("with message:", result) self.assertNotIn("secondsNone", result)
class WaitUntilTest(MarionetteTestCase): def setUp(self): super(WaitUntilTest, self).setUp() self.m = MockMarionette() self.clock = TickingClock() self.wt = Wait(self.m, timeout=10, interval=1, clock=self.clock) def test_true(self): r = self.wt.until(lambda x: x.true()) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_true_within_timeout(self): r = self.wt.until(lambda x: x.true(wait=5)) self.assertTrue(r) self.assertEqual(self.clock.ticks, 4) def test_timeout(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.true(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_exception_raises_immediately(self): with self.assertRaises(TypeError): self.wt.until(lambda x: x.exception(e=TypeError)) self.assertEqual(self.clock.ticks, 0) def test_ignored_exception(self): self.wt.exceptions = (TypeError,) with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.exception(e=TypeError)) def test_ignored_exception_wrapped_in_timeoutexception(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError)) except Exception as e: exc = e s = str(exc) self.assertIsNotNone(exc) self.assertIsInstance(exc, errors.TimeoutException) self.assertIn(", caused by %r" % TypeError, s) self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s) def test_ignored_exception_after_timeout_is_not_raised(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.exception(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_keyboard_interrupt(self): with self.assertRaises(KeyboardInterrupt): self.wt.until(lambda x: x.exception(e=KeyboardInterrupt)) def test_system_exit(self): with self.assertRaises(SystemExit): self.wt.until(lambda x: x.exception(SystemExit)) def test_true_condition_returns_immediately(self): r = self.wt.until(lambda x: x.true()) self.assertIsInstance(r, bool) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_value(self): r = self.wt.until(lambda x: "foo") self.assertEqual(r, "foo") self.assertEqual(self.clock.ticks, 0) def test_custom_predicate(self): r = self.wt.until(lambda x: x.true(wait=2), is_true=at_third_attempt) self.assertTrue(r) self.assertEqual(self.clock.ticks, 1) def test_custom_predicate_times_out(self): with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) self.assertEqual(self.clock.ticks, 2) def test_timeout_elapsed_duration(self): with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 2.0 seconds"): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) def test_timeout_elapsed_rounding(self): wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0) with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 1.0 seconds"): wt.until(lambda x: x.true(), is_true=now) def test_message(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="hooba") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds with message: hooba, caused by", result) def test_no_message(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds, caused by", result) def test_message_has_none_as_its_value(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(False, None, None) except errors.TimeoutException as e: exc = e result = str(exc) self.assertNotIn("with message:", result) self.assertNotIn("secondsNone", result)
def wait_for_obj(self, object): wait = Wait(self.marionette, timeout=5, interval=0.5) try: wait.until(lambda m: m.execute_script("return !!%s;" % object)) except errors.TimeoutException: self.fail("Object '%s' does not exist" % object)
def initiate_outgoing_call(self, destination): self.marionette.execute_script(self.returnable_calls) # use the webapi to initiate a call to the specified number self.marionette.execute_async_script(""" var telephony = window.navigator.mozTelephony; var destination = arguments[0] telephony.dial(destination).then(out_call => { window.wrappedJSObject.received_dialing = false; if (out_call.state == "dialing") { window.wrappedJSObject.received_dialing = true; }; window.wrappedJSObject.received_statechange = false; out_call.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "alerting") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.received_alerting = false; out_call.onalerting = function onalerting(event) { console.log("Received TelephonyCall 'onalerting' event."); if (event.call.state == "alerting") { window.wrappedJSObject.received_alerting = true; window.wrappedJSObject.outgoing_call = out_call; window.wrappedJSObject.returnable_outgoing_call = { number: out_call.number, state: out_call.state }; window.wrappedJSObject.calls = telephony.calls; }; }; window.wrappedJSObject.received_callschanged = false; telephony.oncallschanged = function oncallschanged(event) { console.log("Received Telephony 'oncallschanged' event."); window.wrappedJSObject.received_callschanged = true; }; window.wrappedJSObject.received_busy = false; out_call.onerror = function onerror(event) { console.log("Received TelephonyCall 'onerror' event."); if (event.call.error.name == "BusyError") { window.wrappedJSObject.received_busy = true; }; }; }); window.wrappedJSObject.received_ready = false; telephony.ready.then( function() { console.log("Telephony got ready"); window.wrappedJSObject.received_ready = true; }, function() { console.log("Telephony not ready"); window.wrappedJSObject.received_ready = false; } ); marionetteScriptFinished(1); """, script_args=[destination]) # should have received all events associated with an outgoing call wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_dialing")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_alerting")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_ready")) except: # failed to initiate call; check if the destination phone's line was busy busy = self.marionette.execute_script( "return window.wrappedJSObject.received_busy") self.assertFalse( busy, "Received busy signal; ensure target phone is available and try again" ) self.fail( "Failed to initiate call; mozTelephony.dial is broken -or- there is no network signal. Try again" ) # verify outgoing call state to be 'alerting' self.outgoing_call = self.marionette.execute_script( "return window.wrappedJSObject.returnable_outgoing_call") self.assertEqual(self.outgoing_call['state'], "alerting", "Call state should be 'alerting'")
class WaitUntilTest(MarionetteTestCase): def setUp(self): super(WaitUntilTest, self).setUp() self.m = MockMarionette() self.clock = TickingClock() self.wt = Wait(self.m, timeout=10, interval=1, clock=self.clock) def test_true(self): r = self.wt.until(lambda x: x.true()) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_true_within_timeout(self): r = self.wt.until(lambda x: x.true(wait=5)) self.assertTrue(r) self.assertEqual(self.clock.ticks, 4) def test_timeout(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.true(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_exception_raises_immediately(self): with self.assertRaises(TypeError): self.wt.until(lambda x: x.exception(e=TypeError)) self.assertEqual(self.clock.ticks, 0) def test_ignored_exception(self): self.wt.exceptions = (TypeError,) with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.exception(e=TypeError)) def test_ignored_exception_wrapped_in_timeoutexception(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError)) except Exception as e: exc = e s = str(exc) self.assertIsNotNone(exc) self.assertIsInstance(exc, errors.TimeoutException) self.assertIn(", caused by {0!r}".format(TypeError), s) self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s) def test_ignored_exception_after_timeout_is_not_raised(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.exception(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_keyboard_interrupt(self): with self.assertRaises(KeyboardInterrupt): self.wt.until(lambda x: x.exception(e=KeyboardInterrupt)) def test_system_exit(self): with self.assertRaises(SystemExit): self.wt.until(lambda x: x.exception(SystemExit)) def test_true_condition_returns_immediately(self): r = self.wt.until(lambda x: x.true()) self.assertIsInstance(r, bool) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_value(self): r = self.wt.until(lambda x: "foo") self.assertEqual(r, "foo") self.assertEqual(self.clock.ticks, 0) def test_custom_predicate(self): r = self.wt.until(lambda x: x.true(wait=2), is_true=at_third_attempt) self.assertTrue(r) self.assertEqual(self.clock.ticks, 1) def test_custom_predicate_times_out(self): with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) self.assertEqual(self.clock.ticks, 2) def test_timeout_elapsed_duration(self): with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 2.0 seconds"): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) def test_timeout_elapsed_rounding(self): wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0) with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 1.0 seconds"): wt.until(lambda x: x.true(), is_true=now) def test_timeout_elapsed_interval_by_delayed_condition_return(self): def callback(mn): self.clock.sleep(11) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 11.0 seconds"): self.wt.until(callback) # With a delayed conditional return > timeout, only 1 iteration is possible self.assertEqual(self.m.waited, 1) def test_timeout_with_delayed_condition_return(self): def callback(mn): self.clock.sleep(.5) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 10.0 seconds"): self.wt.until(callback) # With a delayed conditional return < interval, 10 iterations should be possible self.assertEqual(self.m.waited, 10) def test_timeout_interval_shorter_than_delayed_condition_return(self): def callback(mn): self.clock.sleep(2) return mn.false() with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 10.0 seconds"): self.wt.until(callback) # With a delayed return of the conditional which takes twice that long than the interval, # half of the iterations should be possible self.assertEqual(self.m.waited, 5) def test_message(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="hooba") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds with message: hooba, caused by", result) def test_no_message(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds, caused by", result) def test_message_has_none_as_its_value(self): self.wt.exceptions = (TypeError,) exc = None try: self.wt.until(False, None, None) except errors.TimeoutException as e: exc = e result = str(exc) self.assertNotIn("with message:", result) self.assertNotIn("secondsNone", result)
def test_telephony_incoming_multiple(self): # ask user to make first call to the device; answer and verify via webapi self.user_guided_incoming_call() self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['0'], self.incoming_call) self.answer_call() self.assertEqual(self.active_call_list[0]['state'], "connected", "Call state should be 'connected'") self.assertEqual(self.active_call_list[0]['number'], self.incoming_call['number']) self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 1, "There should be 1 active call") # keep call active for a while time.sleep(5) # ask user to again call to the test device; answer and verify via webapi self.user_guided_incoming_call() self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['1'], self.incoming_call) self.assertEqual(self.calls['0'], self.active_call_list[0]) # setup the 'onheld' event handler self.hold_active_call(user_initiate_hold=False) self.answer_call() self.assertEqual(self.active_call_list[1]['state'], "connected", "Call state should be 'connected'") self.assertEqual(self.active_call_list[1]['number'], self.incoming_call['number']) self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 2, "There should be 2 active calls") wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.onheld_call_ok")) wait.until(lambda x: x.execute_script( "return window.wrappedJSObject.received_statechange")) except: # failed to hold self.fail( "Failed to put first active call on hold while second call becomes active" ) onholding = self.marionette.execute_script( "return window.wrappedJSObject.onholding_call_ok") self.assertFalse( onholding, "Telephony.onholding event found, but should not have been " "since the phone user did not initiate holding the call") # keep call active for a while time.sleep(5) # verify call state change self.assertEqual(self.calls['0']['state'], "held", "Call state should be 'held'") self.assertEqual(self.calls['1']['state'], "connected", "Call state should be 'connected'") # disconnect the two active calls self.hangup_call(active_call_selected=1) # verify number of remaining calls and its state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script( "return (window.wrappedJSObject.calls.length == 1)")) self.resume() wait.until(lambda x: x.execute_script( "return (window.wrappedJSObject.calls[0].state == \"connected\")" )) except: self.fail( "Failed to hangup the second call or change the state of first call" ) self.hangup_call(active_call_selected=0) self.calls = self.marionette.execute_script( "return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 0, "There should be 0 calls")
def test_telephony_incoming_multiple(self): # ask user to make first call to the device; answer and verify via webapi self.user_guided_incoming_call() self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['0'], self.incoming_call) self.answer_call() self.assertEqual(self.active_call_list[0]['state'], "connected", "Call state should be 'connected'") self.assertEqual(self.active_call_list[0]['number'], self.incoming_call['number']) self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 1, "There should be 1 active call") # keep call active for a while time.sleep(5) # ask user to again call to the test device; answer and verify via webapi self.user_guided_incoming_call() self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['1'], self.incoming_call) self.assertEqual(self.calls['0'], self.active_call_list[0]) # setup the 'onheld' event handler self.hold_active_call(user_initiate_hold=False) self.answer_call() self.assertEqual(self.active_call_list[1]['state'], "connected", "Call state should be 'connected'") self.assertEqual(self.active_call_list[1]['number'], self.incoming_call['number']) self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 2, "There should be 2 active calls") wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.onheld_call_ok")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) except: # failed to hold self.fail("Failed to put first active call on hold while second call becomes active") onholding = self.marionette.execute_script("return window.wrappedJSObject.onholding_call_ok") self.assertFalse(onholding, "Telephony.onholding event found, but should not have been " "since the phone user did not initiate holding the call") # keep call active for a while time.sleep(5) # verify call state change self.assertEqual(self.calls['0']['state'], "held", "Call state should be 'held'") self.assertEqual(self.calls['1']['state'], "connected", "Call state should be 'connected'") # disconnect the two active calls self.hangup_call(active_call_selected=1) # verify number of remaining calls and its state wait = Wait(self.marionette, timeout=10, interval=0.5) try: wait.until(lambda x: x.execute_script("return (window.wrappedJSObject.calls.length == 1)")) self.resume() wait.until(lambda x: x.execute_script("return (window.wrappedJSObject.calls[0].state == \"connected\")")) except: self.fail("Failed to hangup the second call or change the state of first call") self.hangup_call(active_call_selected=0) self.calls = self.marionette.execute_script("return window.wrappedJSObject.get_returnable_calls()") self.assertEqual(self.calls['length'], 0, "There should be 0 calls")
class WaitUntilTest(MarionetteTestCase): def setUp(self): super(WaitUntilTest, self).setUp() self.m = MockMarionette() self.clock = TickingClock() self.wt = Wait(self.m, timeout=10, interval=1, clock=self.clock) def test_true(self): r = self.wt.until(lambda x: x.true()) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_true_within_timeout(self): r = self.wt.until(lambda x: x.true(wait=5)) self.assertTrue(r) self.assertEqual(self.clock.ticks, 4) def test_timeout(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.true(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_exception_raises_immediately(self): with self.assertRaises(TypeError): self.wt.until(lambda x: x.exception(e=TypeError)) self.assertEqual(self.clock.ticks, 0) def test_ignored_exception(self): self.wt.exceptions = (TypeError, ) with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.exception(e=TypeError)) def test_ignored_exception_wrapped_in_timeoutexception(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError)) except Exception as e: exc = e s = str(exc) self.assertIsNotNone(exc) self.assertIsInstance(exc, errors.TimeoutException) self.assertIn(", caused by %r" % TypeError, s) self.assertIn("self.wt.until(lambda x: x.exception(e=TypeError))", s) def test_ignored_exception_after_timeout_is_not_raised(self): with self.assertRaises(errors.TimeoutException): r = self.wt.until(lambda x: x.exception(wait=15)) self.assertEqual(self.clock.ticks, 10) def test_keyboard_interrupt(self): with self.assertRaises(KeyboardInterrupt): self.wt.until(lambda x: x.exception(e=KeyboardInterrupt)) def test_system_exit(self): with self.assertRaises(SystemExit): self.wt.until(lambda x: x.exception(SystemExit)) def test_true_condition_returns_immediately(self): r = self.wt.until(lambda x: x.true()) self.assertIsInstance(r, bool) self.assertTrue(r) self.assertEqual(self.clock.ticks, 0) def test_value(self): r = self.wt.until(lambda x: "foo") self.assertEqual(r, "foo") self.assertEqual(self.clock.ticks, 0) def test_custom_predicate(self): r = self.wt.until(lambda x: x.true(wait=2), is_true=at_third_attempt) self.assertTrue(r) self.assertEqual(self.clock.ticks, 1) def test_custom_predicate_times_out(self): with self.assertRaises(errors.TimeoutException): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) self.assertEqual(self.clock.ticks, 2) def test_timeout_elapsed_duration(self): with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 2.0 seconds"): self.wt.until(lambda x: x.true(wait=4), is_true=at_third_attempt) def test_timeout_elapsed_rounding(self): wt = Wait(self.m, clock=SequenceClock([1, 0.01, 1]), timeout=0) with self.assertRaisesRegexp(errors.TimeoutException, "Timed out after 1.0 seconds"): wt.until(lambda x: x.true(), is_true=now) def test_message(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="hooba") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds with message: hooba, caused by", result) def test_no_message(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(lambda x: x.exception(e=TypeError), message="") except errors.TimeoutException as e: exc = e result = str(exc) self.assertIn("seconds, caused by", result) def test_message_has_none_as_its_value(self): self.wt.exceptions = (TypeError, ) exc = None try: self.wt.until(False, None, None) except errors.TimeoutException as e: exc = e result = str(exc) self.assertNotIn("with message:", result) self.assertNotIn("secondsNone", result)
def hangup_call(self, call_type="Active", remote_hangup=False, active_call_selected=0): # hangup the active/incoming call, verify self.marionette.execute_async_script(""" var call_type = arguments[0]; var remote_hangup = arguments[1]; var active_call_selected = arguments[2]; window.wrappedJSObject.rcvd_error = false; if (call_type == "Incoming") { var call_to_hangup = window.wrappedJSObject.incoming_call; } else if (call_type == "Outgoing") { var call_to_hangup = window.wrappedJSObject.outgoing_call; } else { if (active_call_selected >=0 && active_call_selected < window.wrappedJSObject.calls.length) { var call_to_hangup = window.wrappedJSObject.calls[active_call_selected]; } else { window.wrappedJSObject.rcvd_error = true; marionetteScriptFinished(0); } }; window.wrappedJSObject.received_statechange = false; call_to_hangup.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "disconnected") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.disconnected_call_ok = false; call_to_hangup.ondisconnected = function ondisconnected(event) { console.log("Received 'ondisconnected' call event."); if (event.call.state == "disconnected") { window.wrappedJSObject.disconnected_call_ok = true; }; }; if (!remote_hangup) { call_to_hangup.hangUp(); } marionetteScriptFinished(1); """, script_args=[call_type, remote_hangup, active_call_selected]) if remote_hangup == False: if self.marionette.execute_script("return window.wrappedJSObject.rcvd_error;"): self.fail("Received invalid value for active_call_selected") # should have received both events associated with a active call hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.disconnected_call_ok")) except: # failed to hangup self.fail("Failed to hangup call") else: self.instruct("Hangup the call from secondary phone and press 'OK'") # should have received only disconnected event associated with a active call hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.disconnected_call_ok")) except: # failed to hangup self.fail("Failed to hangup call") # verify that the call disconnected from phone which is not the device under test disconnecting = self.marionette.execute_script("return window.wrappedJSObject.disconnecting_call_ok") self.assertFalse(disconnecting, "Telephony.ondisconnecting event found, but should not have been " "since the call was terminated remotely") # should have received events associated with a state and calls change for with or without remote hangup wait = Wait(self.marionette, timeout=90, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_callschanged")) except: self.fail("Failed to receive either statechange or callschanged events") # remove the call from list if call_type == "Active": self.active_call_list.pop(active_call_selected)
def initiate_outgoing_call(self, destination): self.marionette.execute_script(self.returnable_calls) # use the webapi to initiate a call to the specified number self.marionette.execute_async_script(""" var telephony = window.navigator.mozTelephony; var destination = arguments[0] telephony.dial(destination).then(out_call => { window.wrappedJSObject.received_dialing = false; if (out_call.state == "dialing") { window.wrappedJSObject.received_dialing = true; }; window.wrappedJSObject.received_statechange = false; out_call.onstatechange = function onstatechange(event) { console.log("Received TelephonyCall 'onstatechange' event."); if (event.call.state == "alerting") { window.wrappedJSObject.received_statechange = true; }; }; window.wrappedJSObject.received_alerting = false; out_call.onalerting = function onalerting(event) { console.log("Received TelephonyCall 'onalerting' event."); if (event.call.state == "alerting") { window.wrappedJSObject.received_alerting = true; window.wrappedJSObject.outgoing_call = out_call; window.wrappedJSObject.returnable_outgoing_call = { number: out_call.number, state: out_call.state }; window.wrappedJSObject.calls = telephony.calls; }; }; window.wrappedJSObject.received_callschanged = false; telephony.oncallschanged = function oncallschanged(event) { console.log("Received Telephony 'oncallschanged' event."); window.wrappedJSObject.received_callschanged = true; }; window.wrappedJSObject.received_busy = false; out_call.onerror = function onerror(event) { console.log("Received TelephonyCall 'onerror' event."); if (event.call.error.name == "BusyError") { window.wrappedJSObject.received_busy = true; }; }; }); window.wrappedJSObject.received_ready = false; telephony.ready.then( function() { console.log("Telephony got ready"); window.wrappedJSObject.received_ready = true; }, function() { console.log("Telephony not ready"); window.wrappedJSObject.received_ready = false; } ); marionetteScriptFinished(1); """, script_args=[destination]) # should have received all events associated with an outgoing call wait = Wait(self.marionette, timeout=30, interval=0.5) try: wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_dialing")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_statechange")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_alerting")) wait.until(lambda x: x.execute_script("return window.wrappedJSObject.received_ready")) except: # failed to initiate call; check if the destination phone's line was busy busy = self.marionette.execute_script("return window.wrappedJSObject.received_busy") self.assertFalse(busy, "Received busy signal; ensure target phone is available and try again") self.fail("Failed to initiate call; mozTelephony.dial is broken -or- there is no network signal. Try again") # verify outgoing call state to be 'alerting' self.outgoing_call = self.marionette.execute_script("return window.wrappedJSObject.returnable_outgoing_call") self.assertEqual(self.outgoing_call['state'], "alerting", "Call state should be 'alerting'")