Exemplo n.º 1
0
    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")
Exemplo n.º 2
0
    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")
Exemplo n.º 3
0
    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")
Exemplo n.º 4
0
    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")
Exemplo n.º 5
0
    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")
Exemplo n.º 6
0
    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")
Exemplo n.º 7
0
    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")
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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_remote_video(self):
        video_wrapper = self.wait_for_element_displayed(
            By.CSS_SELECTOR, ".media .OT_subscriber .OT_video-container", 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_remote_video()

    def local_check_remote_video(self):
        self.switch_to_chatbox()
        self.check_remote_video()

    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()

        # hangup the call
        self.local_leave_room_and_verify_feedback()

    def tearDown(self):
        self.loop_test_servers.shutdown()
        MarionetteTestCase.tearDown(self)
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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()
Exemplo n.º 14
0
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 > 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_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_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 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()

        # 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()

        # 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)
Exemplo n.º 15
0
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)
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
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()
Exemplo n.º 18
0
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-call-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)

        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)
Exemplo n.º 19
0
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()
Exemplo n.º 20
0
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)
Exemplo n.º 21
0
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)
Exemplo n.º 22
0
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)