From fd9f2fc4783cc606734e61116185c032a63d54a0 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 16 Feb 2022 22:01:38 +0100 Subject: fix out-of-source builds --- test/haketilo_test/unit/test_broadcast.py | 175 ++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 test/haketilo_test/unit/test_broadcast.py (limited to 'test/haketilo_test/unit/test_broadcast.py') diff --git a/test/haketilo_test/unit/test_broadcast.py b/test/haketilo_test/unit/test_broadcast.py new file mode 100644 index 0000000..7c2c051 --- /dev/null +++ b/test/haketilo_test/unit/test_broadcast.py @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: CC0-1.0 + +""" +Haketilo unit tests - message broadcasting +""" + +# This file is part of Haketilo +# +# Copyright (C) 2021, Wojtek Kosior +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the CC0 1.0 Universal License as published by +# the Creative Commons Corporation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# CC0 1.0 Universal License for more details. + +import pytest +from selenium.webdriver.support.ui import WebDriverWait + +from ..script_loader import load_script +from .utils import broker_js + +test_page_html = ''' + + +

d0 (channel `somebodyoncetoldme`)

+
+

d1 (channel `worldisgonnarollme`)

+
+

d2 (both channels)

+
+''' + +@pytest.mark.ext_data({ + 'background_script': broker_js, + 'test_page': test_page_html, + 'extra_files': { + 'testpage.js': lambda: load_script('common/broadcast.js') + } +}) +@pytest.mark.usefixtures('webextension') +def test_broadcast(driver, execute_in_page, wait_elem_text): + """ + A test that verifies the broadcasting system based on WebExtension messaging + API and implemented in `background/broadcast_broker.js` and + `common/broadcast.js` works correctly. + """ + # The broadcast facility is meant to enable message distribution between + # multiple contexts (e.g. different tabs/windows). Let's open the same + # extension's test page in a second window. + driver.execute_script( + ''' + window.open(window.location.href, "_blank"); + window.open(window.location.href, "_blank"); + ''') + WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) == 3) + windows = [*driver.window_handles] + + # Let's first test if a simple message can be successfully broadcasted + driver.switch_to.window(windows[0]) + execute_in_page( + ''' + const divs = [0, 1, 2].map(n => document.getElementById("d" + n)); + let appender = n => (t => divs[n].append("\\n" + `[${t[0]}, ${t[1]}]`)); + let listener0 = listener_connection(appender(0)); + subscribe(listener0, "somebodyoncetoldme"); + ''') + + driver.switch_to.window(windows[1]) + execute_in_page( + ''' + let sender0 = sender_connection(); + out(sender0, "somebodyoncetoldme", "iaintthesharpesttool"); + ''') + + driver.switch_to.window(windows[0]) + wait_elem_text('d0', '[somebodyoncetoldme, iaintthesharpesttool]') + + # Let's add 2 more listeners + driver.switch_to.window(windows[0]) + execute_in_page( + ''' + let listener1 = listener_connection(appender(1)); + subscribe(listener1, "worldisgonnarollme"); + let listener2 = listener_connection(appender(2)); + subscribe(listener2, "worldisgonnarollme"); + subscribe(listener2, "somebodyoncetoldme"); + ''') + + # Let's send one message to one channel and one to the other. Verify they + # were received by the rght listeners. + driver.switch_to.window(windows[1]) + execute_in_page( + ''' + out(sender0, "somebodyoncetoldme", "intheshed"); + out(sender0, "worldisgonnarollme", "shewaslooking"); + ''') + + driver.switch_to.window(windows[0]) + wait_elem_text('d0', 'intheshed') + wait_elem_text('d1', 'shewaslooking') + wait_elem_text('d2', 'intheshed') + wait_elem_text('d2', 'shewaslooking') + + text = execute_in_page('returnval(divs[0].innerText);') + assert 'shewaslooking' not in text + text = execute_in_page('returnval(divs[1].innerText);') + assert 'intheshed' not in text + + # Let's create a second sender in third window and use it to send messages + # with the 'prepare' feature. + driver.switch_to.window(windows[2]) + execute_in_page( + ''' + let sender1 = sender_connection(); + prepare(sender1, "somebodyoncetoldme", "kindadumb"); + out(sender1, "worldisgonnarollme", "withherfinger"); + ''') + + driver.switch_to.window(windows[0]) + wait_elem_text('d1', 'withherfinger') + text = execute_in_page('returnval(divs[0].innerText);') + assert 'kindadumb' not in text + + driver.switch_to.window(windows[2]) + execute_in_page('flush(sender1);') + + driver.switch_to.window(windows[0]) + wait_elem_text('d0', 'kindadumb') + + # Let's verify that prepare()'d messages are properly discarded when + # discard() is called. + driver.switch_to.window(windows[2]) + execute_in_page( + ''' + prepare(sender1, "somebodyoncetoldme", "andherthumb"); + discard(sender1); + prepare(sender1, "somebodyoncetoldme", "andhermiddlefinger"); + flush(sender1); + ''') + + driver.switch_to.window(windows[0]) + wait_elem_text('d0', 'andhermiddlefinger') + text = execute_in_page('returnval(divs[0].innerText);') + assert 'andherthumb' not in text + + # Let's verify prepare()'d messages are properly auto-flushed when the other + # end of the connection gets killed (e.g. because browser tab gets closed). + driver.switch_to.window(windows[2]) + execute_in_page( + ''' + prepare(sender1, "worldisgonnarollme", "intheshape", 500); + ''') + driver.close() + + driver.switch_to.window(windows[0]) + wait_elem_text('d2', 'intheshape') + + # Verify listener's connection gets closed properly. + execute_in_page('close(listener0); close(listener1);') + + driver.switch_to.window(windows[1]) + execute_in_page('out(sender0, "worldisgonnarollme", "ofanL");') + execute_in_page('out(sender0, "somebodyoncetoldme", "forehead");') + + driver.switch_to.window(windows[0]) + wait_elem_text('d2', 'ofanL') + wait_elem_text('d2', 'forehead') + for i in (0, 1): + text = execute_in_page('returnval(divs[arguments[0]].innerText);', i) + assert 'ofanL' not in text + assert 'forehead' not in text -- cgit v1.2.3