class Test1BrowserCall(MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) # Unfortunately, enforcing preferences currently comes with the side # effect of launching and restarting the browser before running the # real functional tests. Bug 1048554 has been filed to track this. self.marionette.enforce_gecko_prefs(FIREFOX_PREFERENCES) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") # taken from https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L858 # XXX factor out into utility object for use by other tests def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: m.find_element(by, locator).is_displayed()) return self.marionette.find_element(by, locator) # XXX workaround for Marionette bug 1055309 def wait_for_element_exists(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]) \ .until(lambda m: m.find_element(by, locator)) return self.marionette.find_element(by, locator) def switch_to_panel(self): button = self.marionette.find_element(By.ID, "loop-button") # click the element button.click() # switch to the frame frame = self.marionette.find_element(By.ID, "loop") self.marionette.switch_to_frame(frame) def load_and_verify_standalone_ui(self, url): self.marionette.set_context("content") self.marionette.navigate(url) def start_a_conversation(self): # TODO: wait for react elements sleep(2) button = self.marionette.find_element(By.CSS_SELECTOR, ".rooms .btn-info") # click the element button.click() def get_and_verify_call_url(self): # in the new room model we have to first start a conversation self.start_a_conversation() # TODO: wait for react elements sleep(2) call_url = self.marionette.find_element(By.CLASS_NAME, \ "room-url-link").text self.assertIn(urlparse.urlparse(call_url).scheme, ['http', 'https'], "call URL returned by server " + call_url + " has invalid scheme") return call_url def start_and_verify_outgoing_call(self): # TODO: wait for react elements sleep(2) # make the call! call_button = self.marionette.find_element(By.CLASS_NAME, "btn-join") call_button.click() def accept_and_verify_incoming_call(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1055309 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ("return document.getAnonymousElementByAttribute(" "arguments[0], 'class', 'chat-frame');") frame = self.marionette.execute_script(script, [chatbox]) self.marionette.switch_to_frame(frame) # expect a video container on desktop side video = self.wait_for_element_displayed(By.CLASS_NAME, "media") self.assertEqual(video.tag_name, "div", "expect a video container") def hangup_call_and_verify_feedback(self): self.marionette.set_context("chrome") button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") # XXX bug 1080095 For whatever reason, the click doesn't take effect # unless we wait for a bit (even if we wait for the element to # actually be displayed first, which we're not currently bothering # with). It's not entirely clear whether the click is being # delivered in this case, or whether there's a Marionette bug here. sleep(5) button.click() # check that the feedback form is displayed feedback_form = self.wait_for_element_displayed(By.CLASS_NAME, "faces") self.assertEqual(feedback_form.tag_name, "div", "expect feedback form") def test_1_browser_call(self): self.switch_to_panel() call_url = self.get_and_verify_call_url() # load the link clicker interface into the current content browser self.load_and_verify_standalone_ui(call_url) self.start_and_verify_outgoing_call() # Switch to the conversation window and answer self.accept_and_verify_incoming_call() # Let's wait for the call/media to get established. # TODO: replace this with some media detection sleep(5) # hangup the call self.hangup_call_and_verify_feedback() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test1BrowserCall(MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) # Unfortunately, enforcing preferences currently comes with the side # effect of launching and restarting the browser before running the # real functional tests. Bug 1048554 has been filed to track this. self.marionette.enforce_gecko_prefs(FIREFOX_PREFERENCES) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") # taken from https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L858 # XXX factor out into utility object for use by other tests def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: m.find_element(by, locator).is_displayed()) return self.marionette.find_element(by, locator) def wait_for_subelement_displayed(self, parent, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: parent.find_element(by, locator).is_displayed()) return parent.find_element(by, locator) # XXX workaround for Marionette bug 1094246 def wait_for_element_exists(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]) \ .until(lambda m: m.find_element(by, locator)) return self.marionette.find_element(by, locator) def wait_for_element_enabled(self, element, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.is_enabled(), message="Timed out waiting for element to be enabled") def wait_for_element_attribute_to_be_false(self, element, attribute, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.get_attribute(attribute) == "false", message="Timeout out waiting for " + attribute + " to be false") def switch_to_panel(self): button = self.marionette.find_element(By.ID, "loop-button") # click the element button.click() # switch to the frame frame = self.marionette.find_element(By.ID, "loop-panel-iframe") self.marionette.switch_to_frame(frame) def switch_to_chatbox(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ("return document.getAnonymousElementByAttribute(" "arguments[0], 'class', 'chat-frame');") frame = self.marionette.execute_script(script, [chatbox]) self.marionette.switch_to_frame(frame) def switch_to_standalone(self): self.marionette.set_context("content") def local_start_a_conversation(self): button = self.wait_for_element_displayed(By.CSS_SELECTOR, ".new-room-view .btn-info") self.wait_for_element_enabled(button, 120) button.click() def local_check_room_self_video(self): self.switch_to_chatbox() # expect a video container on desktop side media_container = self.wait_for_element_displayed(By.CLASS_NAME, "media-layout") self.assertEqual(media_container.tag_name, "div", "expect a video container") self.check_video(".local-video") def local_get_and_verify_room_url(self): self.switch_to_chatbox() button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-copy") button.click() # click the element room_url = pyperclip.paste() self.assertIn(urlparse.urlparse(room_url).scheme, ['http', 'https'], "room URL returned by server: '" + room_url + "' has invalid scheme") return room_url def standalone_load_and_join_room(self, url): self.switch_to_standalone() self.marionette.navigate(url) # Join the room join_button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-join") join_button.click() # Assumes the standalone or the conversation window is selected first. def check_video(self, selector): video = self.wait_for_element_displayed(By.CSS_SELECTOR, selector, 20) self.wait_for_element_attribute_to_be_false(video, "paused") self.assertEqual(video.get_attribute("ended"), "false") def standalone_check_remote_video(self): self.switch_to_standalone() self.check_video(".remote-video") def local_check_remote_video(self): self.switch_to_chatbox() self.check_video(".remote-video") def send_chat_message(self, text): """ Sends a chat message using the current context. :param text: The text to send. """ chatbox = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-box > form > input") chatbox.send_keys(text + "\n") def check_received_message(self, expectedText): """ Checks a chat message has been received in the current context. The test assumes only one chat message will be received during the tests. :param expectedText: The expected text of the chat message. """ text_entry = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-entry.received > p > span") self.assertEqual(text_entry.text, expectedText, "should have received the correct message") def check_text_messaging(self): """ Checks text messaging between the generator and clicker in a bi-directional fashion. """ # Send a message using the link generator. self.switch_to_chatbox() self.send_chat_message("test1") # Now check the result on the link clicker. self.switch_to_standalone() self.check_received_message("test1") # Then send a message using the standalone. self.send_chat_message("test2") # Finally check the link generator got it. self.switch_to_chatbox() self.check_received_message("test2") def standalone_check_remote_screenshare(self): self.switch_to_standalone() self.check_video(".screen-share-video") def remote_leave_room(self): self.switch_to_standalone() button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") button.click() self.switch_to_chatbox() # check that the local view reverts to the preview mode self.wait_for_element_displayed(By.CLASS_NAME, "room-invitation-content") def local_get_chatbox_window_expr(self, expr): """ :expr: a sub-expression which must begin with a property of the global content window (e.g. "location.path") :return: the value of the given sub-expression as evaluated in the chatbox content window """ self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ''' let chatBrowser = document.getAnonymousElementByAttribute( arguments[0], 'class', 'chat-frame') // note that using wrappedJSObject waives X-ray vision, which // has security implications, but because we trust the code // running in the chatbox, it should be reasonably safe let chatGlobal = chatBrowser.contentWindow.wrappedJSObject; return chatGlobal.''' + expr return self.marionette.execute_script(script, [chatbox]) def local_get_media_start_time(self): return self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver._getTwoWayMediaStartTime()") # XXX could be memoized def local_get_media_start_time_uninitialized(self): return self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver.CONNECTION_START_TIME_UNINITIALIZED" ) def local_check_media_start_time_uninitialized(self): self.assertEqual( self.local_get_media_start_time(), self.local_get_media_start_time_uninitialized(), "media start time should be uninitialized before " "link clicker enters room") def local_check_media_start_time_initialized(self): self.assertNotEqual( self.local_get_media_start_time(), self.local_get_media_start_time_uninitialized(), "media start time should be initialized after " "media is bidirectionally connected") def local_check_connection_length_noted(self): noted_calls = self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver._connectionLengthNotedCalls") self.assertGreater(noted_calls, 0, "OTSdkDriver._connectionLengthNotedCalls should be " "> 0, noted_calls = " + str(noted_calls)) def test_1_browser_call(self): self.switch_to_panel() self.local_start_a_conversation() # Check the self video in the conversation window self.local_check_room_self_video() # make sure that the media start time is not initialized self.local_check_media_start_time_uninitialized() room_url = self.local_get_and_verify_room_url() # load the link clicker interface into the current content browser self.standalone_load_and_join_room(room_url) # Check we get the video streams self.standalone_check_remote_video() self.local_check_remote_video() # Check text messaging self.check_text_messaging() # since bi-directional media is connected, make sure we've set # the start time self.local_check_media_start_time_initialized() # Check that screenshare was automatically started self.standalone_check_remote_screenshare() # We hangup on the remote (standalone) side, because this also leaves # the local chatbox with the local publishing media still connected, # which means that the local_check_connection_length below # verifies that the connection is noted at the time the remote media # drops, rather than waiting until the window closes. self.remote_leave_room() self.local_check_connection_length_noted() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test1BrowserCall(MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) # Unfortunately, enforcing preferences currently comes with the side # effect of launching and restarting the browser before running the # real functional tests. Bug 1048554 has been filed to track this. self.marionette.enforce_gecko_prefs(FIREFOX_PREFERENCES) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") # taken from https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L858 # XXX factor out into utility object for use by other tests def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: m.find_element(by, locator).is_displayed()) return self.marionette.find_element(by, locator) def wait_for_subelement_displayed(self, parent, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: parent.find_element(by, locator).is_displayed()) return parent.find_element(by, locator) # XXX workaround for Marionette bug 1094246 def wait_for_element_exists(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]) \ .until(lambda m: m.find_element(by, locator)) return self.marionette.find_element(by, locator) def wait_for_element_enabled(self, element, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.is_enabled(), message="Timed out waiting for element to be enabled") def wait_for_element_attribute_to_be_false(self, element, attribute, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.get_attribute(attribute) == "false", message="Timeout out waiting for " + attribute + " to be false") def switch_to_panel(self): button = self.marionette.find_element(By.ID, "loop-button") # click the element button.click() # switch to the frame frame = self.marionette.find_element(By.ID, "loop-panel-iframe") self.marionette.switch_to_frame(frame) def switch_to_chatbox(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ("return document.getAnonymousElementByAttribute(" "arguments[0], 'class', 'chat-frame');") frame = self.marionette.execute_script(script, [chatbox]) self.marionette.switch_to_frame(frame) def switch_to_standalone(self): self.marionette.set_context("content") def local_start_a_conversation(self): button = self.marionette.find_element(By.CSS_SELECTOR, ".rooms .btn-info") self.wait_for_element_enabled(button, 120) button.click() def local_check_room_self_video(self): self.switch_to_chatbox() # expect a video container on desktop side media_container = self.wait_for_element_displayed(By.CLASS_NAME, "media") self.assertEqual(media_container.tag_name, "div", "expect a video container") def local_get_and_verify_room_url(self): button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-copy") button.click() # click the element room_url = pyperclip.paste() self.assertIn(urlparse.urlparse(room_url).scheme, ['http', 'https'], "room URL returned by server " + room_url + " has invalid scheme") return room_url def standalone_load_and_join_room(self, url): self.switch_to_standalone() self.marionette.navigate(url) # Join the room join_button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-join") join_button.click() # Assumes the standlone or the conversation window is selected first. def check_video(self, selector): video_wrapper = self.wait_for_element_displayed(By.CSS_SELECTOR, selector, 20) video = self.wait_for_subelement_displayed(video_wrapper, By.TAG_NAME, "video") self.wait_for_element_attribute_to_be_false(video, "paused") self.assertEqual(video.get_attribute("ended"), "false") def standalone_check_remote_video(self): self.switch_to_standalone() self.check_video(".remote .OT_subscriber .OT_widget-container") def local_check_remote_video(self): self.switch_to_chatbox() self.check_video(".remote .OT_subscriber .OT_widget-container") def local_enable_screenshare(self): self.switch_to_chatbox() button = self.marionette.find_element(By.CLASS_NAME, "btn-screen-share") button.click() def standalone_check_remote_screenshare(self): self.switch_to_standalone() self.check_video(".media .screen .OT_subscriber .OT_widget-container") def local_leave_room_and_verify_feedback(self): button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") button.click() # check that the feedback form is displayed feedback_form = self.wait_for_element_displayed(By.CLASS_NAME, "faces") self.assertEqual(feedback_form.tag_name, "div", "expect feedback form") def test_1_browser_call(self): self.switch_to_panel() self.local_start_a_conversation() # Check the self video in the conversation window self.local_check_room_self_video() room_url = self.local_get_and_verify_room_url() # load the link clicker interface into the current content browser self.standalone_load_and_join_room(room_url) # Check we get the video streams self.standalone_check_remote_video() self.local_check_remote_video() # XXX To enable this, we either need to navigate the permissions prompt # or have a route where we don't need the permissions prompt. # self.local_enable_screenshare() # self.standalone_check_remote_screenshare() # hangup the call self.local_leave_room_and_verify_feedback() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test1BrowserCall(MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) # Unfortunately, enforcing preferences currently comes with the side # effect of launching and restarting the browser before running the # real functional tests. Bug 1048554 has been filed to track this. self.marionette.enforce_gecko_prefs(FIREFOX_PREFERENCES) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") # taken from https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L858 # XXX factor out into utility object for use by other tests def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: m.find_element(by, locator).is_displayed()) return self.marionette.find_element(by, locator) # XXX workaround for Marionette bug 1055309 def wait_for_element_exists(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]) \ .until(lambda m: m.find_element(by, locator)) return self.marionette.find_element(by, locator) def switch_to_panel(self): button = self.marionette.find_element(By.ID, "loop-button-throttled") # click the element button.click() # switch to the frame frame = self.marionette.find_element(By.ID, "loop") self.marionette.switch_to_frame(frame) def load_and_verify_standalone_ui(self, url): self.marionette.set_context("content") self.marionette.navigate(url) call_url_link = self.marionette.find_element(By.CLASS_NAME, "call-url") \ .text self.assertEqual(url, call_url_link, "should be on the correct page") def get_and_verify_call_url(self): # get and check for a call url url_input_element = self.wait_for_element_displayed(By.TAG_NAME, "input") # wait for pending state to finish self.assertEqual(url_input_element.get_attribute("class"), "pending", "expect the input to be pending") # get and check the input (the "callUrl" class is only added after # the pending class is removed and the URL has arrived). # # XXX should investigate getting rid of the fragile and otherwise # unnecessary callUrl class and replacing this with a By.CSS_SELECTOR # and some possible combination of :not and/or an attribute selector # once bug 1048551 is fixed. url_input_element = self.wait_for_element_displayed(By.CLASS_NAME, "callUrl") call_url = url_input_element.get_attribute("value") self.assertNotEqual(call_url, u'', "input is populated with call URL after pending" " is finished") self.assertIn(urlparse.urlparse(call_url).scheme, ['http', 'https'], "call URL returned by server " + call_url + " has invalid scheme") return call_url def start_and_verify_outgoing_call(self): # make the call! call_button = self.marionette.find_element(By.CLASS_NAME, "btn-accept") call_button.click() # make sure the standalone progresses to the pending state pending_header = self.wait_for_element_displayed(By.CLASS_NAME, "pending-header") self.assertEqual(pending_header.tag_name, "header", "expect a pending header") def accept_and_verify_incoming_call(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1055309 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ("return document.getAnonymousElementByAttribute(" "arguments[0], 'class', 'chat-frame');") frame = self.marionette.execute_script(script, [chatbox]) self.marionette.switch_to_frame(frame) # Accept the incoming call call_button = self.marionette.find_element(By.CLASS_NAME, "btn-accept") # accept call from the desktop side call_button.click() # expect a video container on desktop side video = self.wait_for_element_displayed(By.CLASS_NAME, "media") self.assertEqual(video.tag_name, "div", "expect a video container") def hangup_call_and_verify_feedback(self): self.marionette.set_context("chrome") button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") # XXX For whatever reason, the click doesn't take effect unless we # wait for a bit (even if we wait for the element to actually be # displayed first, which we're not currently bothering with). It's # not entirely clear whether the click is being delivered in this case, # or whether there's a Marionette bug here. sleep(2) button.click() # check that the feedback form is displayed feedback_form = self.wait_for_element_displayed(By.CLASS_NAME, "faces") self.assertEqual(feedback_form.tag_name, "div", "expect feedback form") def test_1_browser_call(self): self.switch_to_panel() call_url = self.get_and_verify_call_url() # load the link clicker interface into the current content browser self.load_and_verify_standalone_ui(call_url) self.start_and_verify_outgoing_call() # Switch to the conversation window and answer self.accept_and_verify_incoming_call() # hangup the call self.hangup_call_and_verify_feedback() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test1BrowserCall(LoopTestDriver, MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) LoopTestDriver.setUp(self, self.marionette) # Although some of these preferences might require restart, we don't # use enforce_gecko_prefs (which would restart), as we need to restart # for the add-on installation anyway. self.marionette.set_prefs(FIREFOX_PREFERENCES) xpi_file = os.environ.get("LOOP_XPI_FILE") if xpi_file: addons = Addons(self.marionette) # XXX We should really use temp=True here, but due to the later # restart to ensure the add-on is installed correctly, this won't work # at the moment. What we need is a fully restartless add-on - bug 1229352 # at which point we should be able to make this install temporarily # and after the restart. addons.install(os.path.abspath(xpi_file)) self.e10s_enabled = os.environ.get("TEST_E10S") == "1" # Restart the browser nicely, so the preferences and add-on installation # take full effect. self.marionette.restart(in_app=True) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") def standalone_check_remote_video(self): self.switch_to_standalone() self.check_video(".remote-video") def local_check_remote_video(self): self.switch_to_chatbox() self.check_video(".remote-video") def send_chat_message(self, text): """ Sends a chat message using the current context. :param text: The text to send. """ chatbox = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-box > form > input") chatbox.send_keys(text + "\n") def check_received_message(self, expectedText): """ Checks a chat message has been received in the current context. The test assumes only one chat message will be received during the tests. :param expectedText: The expected text of the chat message. """ text_entry = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-entry.received > p") self.assertEqual(text_entry.text, expectedText, "should have received the correct message") def check_text_messaging(self): """ Checks text messaging between the generator and clicker in a bi-directional fashion. """ # Send a message using the link generator. self.switch_to_chatbox() self.send_chat_message("test1") # Now check the result on the link clicker. self.switch_to_standalone() self.check_received_message("test1") # Then send a message using the standalone. self.send_chat_message("test2") # Finally check the link generator got it. self.switch_to_chatbox() self.check_received_message("test2") def standalone_check_remote_screenshare(self): self.switch_to_standalone() self.check_video(".screen-share-video") def remote_leave_room(self): self.switch_to_standalone() button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") button.click() self.switch_to_chatbox() # check that the local view reverts to the preview mode self.wait_for_element_displayed(By.CLASS_NAME, "room-invitation-content") def local_leave_room(self): button = self.marionette.find_element(By.CLASS_NAME, "stop-sharing-button") button.click() def local_get_chatbox_window_expr(self, expr): """ :expr: a sub-expression which must begin with a property of the global content window (e.g. "location.path") :return: the value of the given sub-expression as evaluated in the chatbox content window """ self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ''' let chatBrowser = document.getAnonymousElementByAttribute( arguments[0], 'anonid', 'content') // note that using wrappedJSObject waives X-ray vision, which // has security implications, but because we trust the code // running in the chatbox, it should be reasonably safe let chatGlobal = chatBrowser.contentWindow.wrappedJSObject; return chatGlobal.''' + expr return self.marionette.execute_script(script, [chatbox]) def local_close_conversation(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') close_button = chatbox.find_element(By.ANON_ATTRIBUTE, {"class": "chat-loop-hangup chat-toolbarbutton"}) close_button.click() def check_feedback_form(self): self.switch_to_chatbox() feedbackPanel = self.wait_for_element_displayed(By.CSS_SELECTOR, ".feedback-view-container") self.assertNotEqual(feedbackPanel, "") def check_rename_layout(self): self.switch_to_panel() renameInput = self.wait_for_element_displayed(By.CSS_SELECTOR, ".rename-input") self.assertNotEqual(renameInput, "") def test_1_browser_call(self): # Marionette doesn't make it easy to set up a page to load automatically # on start. So lets load about:home. We need this for now, so that the # various browser checks believe we've enabled e10s. self.load_homepage() self.open_panel() self.switch_to_panel() self.local_start_a_conversation() # Force to close the share panel self.local_close_share_panel() # Check the self video in the conversation window self.local_check_room_self_video() room_url = self.local_get_and_verify_room_url() # load the link clicker interface into the current content browser self.standalone_load_and_join_room(room_url) # Check we get the video streams self.standalone_check_remote_video() self.local_check_remote_video() # Check text messaging self.check_text_messaging() # Check that screenshare was automatically started self.standalone_check_remote_screenshare() # We hangup on the remote (standalone) side, because this also leaves # the local chatbox with the local publishing media still connected, # which means that the local_check_connection_length below # verifies that the connection is noted at the time the remote media # drops, rather than waiting until the window closes. self.remote_leave_room() # Hangup on local will open feedback window first self.local_close_conversation() self.check_feedback_form() # Close the window once again to see the rename layout self.local_close_conversation() self.check_rename_layout() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test2Linkclicker(LoopTestDriver, unittest.TestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() # Set the standalone url for these tests. standalone_url = CONTENT_SERVER_URL + "/" LoopTestDriver.setUp(self, extra_prefs={ "loop.linkClicker.url": standalone_url, "webchannel.allowObject.urlWhitelist": CONTENT_SERVER_URL }) self.e10s_enabled = os.environ.get("TEST_E10S") == "1" # this is browser chrome, kids, not the content window just yet self.driver.set_context("chrome") def navigate_to_standalone(self, url): self.switch_to_standalone() self.driver.get(url) def standalone_check_own_link_view(self): view_container = self.wait_for_element_displayed_by_css_selector( ".handle-user-agent-view-scroller", 30) self.assertEqual(view_container.tag_name, "div", "expect a error container") def local_leave_room(self): self.open_panel() self.switch_to_panel() button = self.driver.find_element_by_class_name("stop-sharing-button") button.click() def standalone_join_own_room(self): button = self.wait_for_element_displayed_by_class_name("btn-info", 30) button.click() def standalone_check_error_text(self): error_container = self.wait_for_element_displayed_by_class_name("failure", 30) self.assertEqual(error_container.tag_name, "p", "expect a error container") def test_2_own_room_test(self): # Marionette doesn't make it easy to set up a page to load automatically # on start. So lets load about:home. We need this for now, so that the # various browser checks believe we've enabled e10s. self.load_homepage() self.open_panel() self.switch_to_panel() self.local_start_a_conversation() # Force to close the share panel self.local_close_share_panel() room_url = self.local_get_and_verify_room_url() self.local_leave_room() # load the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_check_own_link_view() self.standalone_join_own_room() # Ensure we're on a different page so that we can navigate back to the room url later. self.load_homepage() self.local_check_room_self_video() # reload the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_join_own_room() self.standalone_check_error_text() def tearDown(self): self.loop_test_servers.shutdown() self.driver.quit()
class Test2Linkclicker(LoopTestDriver, MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) LoopTestDriver.setUp(self, self.marionette) standalone_url = CONTENT_SERVER_URL + "/" prefs = copy.copy(FIREFOX_PREFERENCES) prefs["loop.linkClicker.url"] = standalone_url # No trailing slash on this one. prefs["webchannel.allowObject.urlWhitelist"] = CONTENT_SERVER_URL # Although some of these preferences might require restart, we don't # use enforce_gecko_prefs (which would restart), as we need to restart # for the add-on installation anyway. self.marionette.set_prefs(prefs) xpi_file = os.environ.get("LOOP_XPI_FILE") if xpi_file: addons = Addons(self.marionette) # XXX We should really use temp=True here, but due to the later # restart to ensure the add-on is installed correctly, this won't work # at the moment. What we need is a fully restartless add-on - bug 1229352 # at which point we should be able to make this install temporarily # and after the restart. addons.install(os.path.abspath(xpi_file)) self.e10s_enabled = os.environ.get("TEST_E10S") == "1" # Restart the browser nicely, so the preferences and add-on installation # take full effect. self.marionette.restart(in_app=True) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") def navigate_to_standalone(self, url): self.switch_to_standalone() self.marionette.navigate(url) def standalone_check_own_link_view(self): view_container = self.wait_for_element_displayed(By.CSS_SELECTOR, ".handle-user-agent-view-scroller", 30) self.assertEqual(view_container.tag_name, "div", "expect a error container") def local_leave_room(self): self.open_panel() self.switch_to_panel() button = self.marionette.find_element(By.CLASS_NAME, "stop-sharing-button") button.click() def standalone_join_own_room(self): button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-info", 30) button.click() def standalone_check_error_text(self): error_container = self.wait_for_element_displayed(By.CLASS_NAME, "failure", 30) self.assertEqual(error_container.tag_name, "p", "expect a error container") def test_2_own_room_test(self): # Marionette doesn't make it easy to set up a page to load automatically # on start. So lets load about:home. We need this for now, so that the # various browser checks believe we've enabled e10s. self.load_homepage() self.open_panel() self.switch_to_panel() self.local_start_a_conversation() # Force to close the share panel self.local_close_share_panel() room_url = self.local_get_and_verify_room_url() self.local_leave_room() # load the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_check_own_link_view() self.standalone_join_own_room() # Ensure we're on a different page so that we can navigate back to the room url later. self.load_homepage() self.local_check_room_self_video() # reload the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_join_own_room() self.standalone_check_error_text() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test1BrowserCall(LoopTestDriver, unittest.TestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() LoopTestDriver.setUp(self) self.e10s_enabled = os.environ.get("TEST_E10S") == "1" # this is browser chrome, kids, not the content window just yet self.driver.set_context("chrome") def standalone_check_remote_video(self): self.switch_to_standalone() self.check_video(".remote-video") def local_check_remote_video(self): self.switch_to_chatbox() self.check_video(".remote-video") def send_chat_message(self, text): """ Sends a chat message using the current context. :param text: The text to send. """ chatbox = self.wait_for_element_displayed_by_css_selector(".text-chat-box > form > input") chatbox.send_keys(text + "\n") def check_received_message(self, expectedText): """ Checks a chat message has been received in the current context. The test assumes only one chat message will be received during the tests. :param expectedText: The expected text of the chat message. """ text_entry = self.wait_for_element_displayed_by_css_selector(".text-chat-entry.received > p") self.assertEqual(text_entry.text, expectedText, "should have received the correct message") def check_text_messaging(self): """ Checks text messaging between the generator and clicker in a bi-directional fashion. """ # Send a message using the link generator. self.switch_to_chatbox() self.send_chat_message("test1") # Now check the result on the link clicker. self.switch_to_standalone() self.check_received_message("test1") # Then send a message using the standalone. self.send_chat_message("test2") # Finally check the link generator got it. self.switch_to_chatbox() self.check_received_message("test2") def standalone_check_remote_screenshare(self): self.switch_to_standalone() self.check_video(".screen-share-video") def remote_leave_room(self): self.switch_to_standalone() button = self.driver.find_element_by_class_name("btn-hangup") button.click() self.switch_to_chatbox() # check that the local view reverts to the preview mode self.wait_for_element_displayed_by_class_name("room-invitation-content") def local_leave_room(self): button = self.marionette.find_element_by_class_name("stop-sharing-button") button.click() def local_close_conversation(self): self.set_context("chrome") self.driver.switch_to.default_content() script = ("var chatbox = document.getElementsByTagName('chatbox')[0];" "return document.getAnonymousElementByAttribute(" "chatbox, 'class', 'chat-loop-hangup chat-toolbarbutton');") close_button = self.driver.execute_script(script) close_button.click() def check_feedback_form(self): self.switch_to_chatbox() feedbackPanel = self.wait_for_element_displayed_by_css_selector(".feedback-view-container") self.assertNotEqual(feedbackPanel, "") def check_rename_layout(self): self.switch_to_panel() renameInput = self.wait_for_element_displayed_by_css_selector(".rename-input") self.assertNotEqual(renameInput, "") def test_1_browser_call(self): # Marionette doesn't make it easy to set up a page to load automatically # on start. So lets load about:home. We need this for now, so that the # various browser checks believe we've enabled e10s. self.load_homepage() self.open_panel() self.switch_to_panel() self.local_start_a_conversation() # Force to close the share panel self.local_close_share_panel() # Check the self video in the conversation window self.local_check_room_self_video() room_url = self.local_get_and_verify_room_url() # load the link clicker interface into the current content browser self.standalone_load_and_join_room(room_url) # Check we get the video streams self.standalone_check_remote_video() self.local_check_remote_video() # Check text messaging self.check_text_messaging() # Check that screenshare was automatically started self.standalone_check_remote_screenshare() # We hangup on the remote (standalone) side, because this also leaves # the local chatbox with the local publishing media still connected, # which means that the local_check_connection_length below # verifies that the connection is noted at the time the remote media # drops, rather than waiting until the window closes. self.remote_leave_room() # Hangup on local will open feedback window first self.local_close_conversation() self.check_feedback_form() # Close the window once again to see the rename layout self.local_close_conversation() self.check_rename_layout() def tearDown(self): self.loop_test_servers.shutdown() self.driver.quit()
class Test1BrowserCall(MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) # Although some of these preferences might require restart, we don't # use enforce_gecko_prefs (which would restart), as we need to restart # for the add-on installation anyway. self.marionette.set_prefs(FIREFOX_PREFERENCES) xpi_file = os.environ.get("LOOP_XPI_FILE") if xpi_file: addons = Addons(self.marionette) # XXX We should really use temp=True here, but due to the later # restart to ensure the add-on is installed correctly, this won't work # at the moment. What we need is a fully restartless add-on - bug 1229352 # at which point we should be able to make this install temporarily # and after the restart. addons.install(os.path.abspath(xpi_file)) # Restart the browser nicely, so the preferences and add-on installation # take full effect. self.marionette.restart(in_app=True) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") # taken from https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-ui-tests/gaiatest/gaia_test.py#L858 # XXX factor out into utility object for use by other tests def wait_for_element_displayed(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: m.find_element(by, locator).is_displayed()) return self.marionette.find_element(by, locator) def wait_for_subelement_displayed(self, parent, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException])\ .until(lambda m: parent.find_element(by, locator).is_displayed()) return parent.find_element(by, locator) # XXX workaround for Marionette bug 1094246 def wait_for_element_exists(self, by, locator, timeout=None): Wait(self.marionette, timeout, ignored_exceptions=[NoSuchElementException, StaleElementException]) \ .until(lambda m: m.find_element(by, locator)) return self.marionette.find_element(by, locator) def wait_for_element_enabled(self, element, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.is_enabled(), message="Timed out waiting for element to be enabled") def wait_for_element_attribute_to_be_false(self, element, attribute, timeout=10): Wait(self.marionette, timeout) \ .until(lambda e: element.get_attribute(attribute) == "false", message="Timeout out waiting for " + attribute + " to be false") def switch_to_panel(self): button = self.marionette.find_element(By.ID, "loop-button") # click the element button.click() # switch to the frame frame = self.marionette.find_element(By.ID, "loop-panel-iframe") self.marionette.switch_to_frame(frame) def switch_to_chatbox(self): self.marionette.set_context("chrome") self.marionette.switch_to_frame() # Added time lapse to allow for DOM to catch up time.sleep(2) # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ("return document.getAnonymousElementByAttribute(" "arguments[0], 'anonid', 'content');") frame = self.marionette.execute_script(script, [chatbox]) self.marionette.switch_to_frame(frame) def switch_to_standalone(self): self.marionette.set_context("content") def local_start_a_conversation(self): button = self.wait_for_element_displayed(By.CSS_SELECTOR, ".new-room-view .btn-info") self.wait_for_element_enabled(button, 120) button.click() def local_check_room_self_video(self): self.switch_to_chatbox() # expect a video container on desktop side media_container = self.wait_for_element_displayed(By.CLASS_NAME, "media-layout") self.assertEqual(media_container.tag_name, "div", "expect a video container") self.check_video(".local-video") def adjust_url(self, room_url): if USE_LOCAL_STANDALONE != "1": return room_url # If we're not using the local standalone, then we need to adjust the room # url that the server gives us to use the local standalone. return re.sub("https?://.*/", ROOMS_WEB_APP_URL_BASE + "/", room_url) def local_get_and_verify_room_url(self): self.switch_to_chatbox() button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-copy") button.click() # click the element room_url = pyperclip.paste() room_url = self.adjust_url(room_url) self.assertIn(urlparse.urlparse(room_url).scheme, ['http', 'https'], "room URL returned by server: '" + room_url + "' has invalid scheme") return room_url def standalone_load_and_join_room(self, url): self.switch_to_standalone() self.marionette.navigate(url) # Join the room - the first time around, the tour will be displayed # so we look for its close button. tour_close_button = self.wait_for_element_displayed(By.CLASS_NAME, "button-close") tour_close_button.click() # Assumes the standalone or the conversation window is selected first. def check_video(self, selector): video = self.wait_for_element_displayed(By.CSS_SELECTOR, selector, 30) self.wait_for_element_attribute_to_be_false(video, "paused") self.assertEqual(video.get_attribute("ended"), "false") def standalone_check_remote_video(self): self.switch_to_standalone() self.check_video(".remote-video") def local_check_remote_video(self): self.switch_to_chatbox() self.check_video(".remote-video") def send_chat_message(self, text): """ Sends a chat message using the current context. :param text: The text to send. """ chatbox = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-box > form > input") chatbox.send_keys(text + "\n") def check_received_message(self, expectedText): """ Checks a chat message has been received in the current context. The test assumes only one chat message will be received during the tests. :param expectedText: The expected text of the chat message. """ text_entry = self.wait_for_element_displayed(By.CSS_SELECTOR, ".text-chat-entry.received > p > span") self.assertEqual(text_entry.text, expectedText, "should have received the correct message") def check_text_messaging(self): """ Checks text messaging between the generator and clicker in a bi-directional fashion. """ # Send a message using the link generator. self.switch_to_chatbox() self.send_chat_message("test1") # Now check the result on the link clicker. self.switch_to_standalone() self.check_received_message("test1") # Then send a message using the standalone. self.send_chat_message("test2") # Finally check the link generator got it. self.switch_to_chatbox() self.check_received_message("test2") def standalone_check_remote_screenshare(self): self.switch_to_standalone() self.check_video(".screen-share-video") def remote_leave_room(self): self.switch_to_standalone() button = self.marionette.find_element(By.CLASS_NAME, "btn-hangup") button.click() self.switch_to_chatbox() # check that the local view reverts to the preview mode self.wait_for_element_displayed(By.CLASS_NAME, "room-invitation-content") def local_get_chatbox_window_expr(self, expr): """ :expr: a sub-expression which must begin with a property of the global content window (e.g. "location.path") :return: the value of the given sub-expression as evaluated in the chatbox content window """ self.marionette.set_context("chrome") self.marionette.switch_to_frame() # XXX should be using wait_for_element_displayed, but need to wait # for Marionette bug 1094246 to be fixed. chatbox = self.wait_for_element_exists(By.TAG_NAME, 'chatbox') script = ''' let chatBrowser = document.getAnonymousElementByAttribute( arguments[0], 'anonid', 'content') // note that using wrappedJSObject waives X-ray vision, which // has security implications, but because we trust the code // running in the chatbox, it should be reasonably safe let chatGlobal = chatBrowser.contentWindow.wrappedJSObject; return chatGlobal.''' + expr return self.marionette.execute_script(script, [chatbox]) def local_get_media_start_time(self): return self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver._getTwoWayMediaStartTime()") # XXX could be memoized def local_get_media_start_time_uninitialized(self): return self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver.CONNECTION_START_TIME_UNINITIALIZED" ) def local_check_media_start_time_uninitialized(self): self.assertEqual( self.local_get_media_start_time(), self.local_get_media_start_time_uninitialized(), "media start time should be uninitialized before " "link clicker enters room") def local_check_media_start_time_initialized(self): self.assertNotEqual( self.local_get_media_start_time(), self.local_get_media_start_time_uninitialized(), "media start time should be initialized after " "media is bidirectionally connected") def local_check_connection_length_noted(self): noted_calls = self.local_get_chatbox_window_expr( "loop.conversation._sdkDriver._connectionLengthNotedCalls") self.assertGreater(noted_calls, 0, "OTSdkDriver._connectionLengthNotedCalls should be " "> 0, noted_calls = " + str(noted_calls)) def test_1_browser_call(self): self.switch_to_panel() self.local_start_a_conversation() # Check the self video in the conversation window self.local_check_room_self_video() # make sure that the media start time is not initialized self.local_check_media_start_time_uninitialized() room_url = self.local_get_and_verify_room_url() # load the link clicker interface into the current content browser self.standalone_load_and_join_room(room_url) # Check we get the video streams self.standalone_check_remote_video() self.local_check_remote_video() # Check text messaging self.check_text_messaging() # since bi-directional media is connected, make sure we've set # the start time self.local_check_media_start_time_initialized() # Check that screenshare was automatically started self.standalone_check_remote_screenshare() # We hangup on the remote (standalone) side, because this also leaves # the local chatbox with the local publishing media still connected, # which means that the local_check_connection_length below # verifies that the connection is noted at the time the remote media # drops, rather than waiting until the window closes. self.remote_leave_room() self.local_check_connection_length_noted() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)
class Test2Linkclicker(LoopTestDriver, MarionetteTestCase): # XXX Move this to setup class so it doesn't restart the server # after every test. def setUp(self): # start server self.loop_test_servers = LoopTestServers() MarionetteTestCase.setUp(self) LoopTestDriver.setUp(self, self.marionette) standalone_url = CONTENT_SERVER_URL + "/" prefs = copy.copy(FIREFOX_PREFERENCES) prefs["loop.linkClicker.url"] = standalone_url # Although some of these preferences might require restart, we don't # use enforce_gecko_prefs (which would restart), as we need to restart # for the add-on installation anyway. self.marionette.set_prefs(prefs) xpi_file = os.environ.get("LOOP_XPI_FILE") if xpi_file: addons = Addons(self.marionette) # XXX We should really use temp=True here, but due to the later # restart to ensure the add-on is installed correctly, this won't work # at the moment. What we need is a fully restartless add-on - bug 1229352 # at which point we should be able to make this install temporarily # and after the restart. addons.install(os.path.abspath(xpi_file)) self.e10s_enabled = os.environ.get("TEST_E10S") == "1" # Restart the browser nicely, so the preferences and add-on installation # take full effect. self.marionette.restart(in_app=True) # this is browser chrome, kids, not the content window just yet self.marionette.set_context("chrome") def navigate_to_standalone(self, url): self.switch_to_standalone() self.marionette.navigate(url) def standalone_check_own_link_view(self): view_container = self.wait_for_element_displayed( By.CSS_SELECTOR, ".handle-user-agent-view-scroller", 30) self.assertEqual(view_container.tag_name, "div", "expect a error container") def local_leave_room(self): self.open_panel() self.switch_to_panel() button = self.marionette.find_element(By.CLASS_NAME, "stop-sharing-button") button.click() def standalone_join_own_room(self): button = self.wait_for_element_displayed(By.CLASS_NAME, "btn-info", 30) button.click() def standalone_check_error_text(self): error_container = self.wait_for_element_displayed( By.CLASS_NAME, "failure", 30) self.assertEqual(error_container.tag_name, "p", "expect a error container") def test_2_own_room_test(self): # Marionette doesn't make it easy to set up a page to load automatically # on start. So lets load about:home. We need this for now, so that the # various browser checks believe we've enabled e10s. self.load_homepage() self.open_panel() self.switch_to_panel() self.local_start_a_conversation() # Force to close the share panel self.local_close_share_panel() room_url = self.local_get_and_verify_room_url() self.local_leave_room() # load the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_check_own_link_view() self.standalone_join_own_room() # Ensure we're on a different page so that we can navigate back to the room url later. self.load_homepage() self.local_check_room_self_video() # reload the link clicker interface into the current content browser self.navigate_to_standalone(room_url) self.standalone_join_own_room() self.standalone_check_error_text() def tearDown(self): self.loop_test_servers.shutdown() MarionetteTestCase.tearDown(self)