Project

General

Profile

Download (5.91 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / test / unit / test_broadcast.py @ 4c6a2323

1 58fe4c7d Wojtek Kosior
# SPDX-License-Identifier: CC0-1.0
2
3
"""
4
Haketilo unit tests - message broadcasting
5
"""
6
7
# This file is part of Haketilo
8
#
9
# Copyright (C) 2021, Wojtek Kosior
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the CC0 1.0 Universal License as published by
13
# the Creative Commons Corporation.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# CC0 1.0 Universal License for more details.
19
20
import pytest
21 4c6a2323 Wojtek Kosior
from selenium.webdriver.support.ui import WebDriverWait
22 58fe4c7d Wojtek Kosior
23
from ..script_loader import load_script
24 e7d11c7c Wojtek Kosior
from .utils import broker_js
25 58fe4c7d Wojtek Kosior
26
test_page_html = '''
27
<!DOCTYPE html>
28
<script src="/testpage.js"></script>
29
<h2>d0 (channel `somebodyoncetoldme`)</h2>
30
<div id="d0"></div>
31
<h2>d1 (channel `worldisgonnarollme`)</h2>
32
<div id="d1"></div>
33
<h2>d2 (both channels)</h2>
34
<div id="d2"></div>
35
'''
36
37
@pytest.mark.ext_data({
38
    'background_script': broker_js,
39
    'test_page':         test_page_html,
40
    'extra_files': {
41 e7d11c7c Wojtek Kosior
        'testpage.js':   lambda: load_script('common/broadcast.js')
42 58fe4c7d Wojtek Kosior
    }
43
})
44
@pytest.mark.usefixtures('webextension')
45
def test_broadcast(driver, execute_in_page, wait_elem_text):
46
    """
47
    A test that verifies the broadcasting system based on WebExtension messaging
48
    API and implemented in `background/broadcast_broker.js` and
49
    `common/broadcast.js` works correctly.
50
    """
51
    # The broadcast facility is meant to enable message distribution between
52
    # multiple contexts (e.g. different tabs/windows). Let's open the same
53
    # extension's test page in a second window.
54
    driver.execute_script(
55
        '''
56
        window.open(window.location.href, "_blank");
57
        window.open(window.location.href, "_blank");
58
        ''')
59 4c6a2323 Wojtek Kosior
    WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) == 3)
60 58fe4c7d Wojtek Kosior
    windows = [*driver.window_handles]
61
62
    # Let's first test if a simple message can be successfully broadcasted
63
    driver.switch_to.window(windows[0])
64
    execute_in_page(
65
        '''
66
        const divs = [0, 1, 2].map(n => document.getElementById("d" + n));
67
        let appender = n => (t => divs[n].append("\\n" + `[${t[0]}, ${t[1]}]`));
68 b590eaa2 Wojtek Kosior
        let listener0 = listener_connection(appender(0));
69
        subscribe(listener0, "somebodyoncetoldme");
70 58fe4c7d Wojtek Kosior
        ''')
71
72
    driver.switch_to.window(windows[1])
73
    execute_in_page(
74
        '''
75 b590eaa2 Wojtek Kosior
        let sender0 = sender_connection();
76
        out(sender0, "somebodyoncetoldme", "iaintthesharpesttool");
77 58fe4c7d Wojtek Kosior
        ''')
78
79
    driver.switch_to.window(windows[0])
80
    wait_elem_text('d0', '[somebodyoncetoldme, iaintthesharpesttool]')
81
82
    # Let's add 2 more listeners
83
    driver.switch_to.window(windows[0])
84
    execute_in_page(
85
        '''
86 b590eaa2 Wojtek Kosior
        let listener1 = listener_connection(appender(1));
87
        subscribe(listener1, "worldisgonnarollme");
88
        let listener2 = listener_connection(appender(2));
89
        subscribe(listener2, "worldisgonnarollme");
90
        subscribe(listener2, "somebodyoncetoldme");
91 58fe4c7d Wojtek Kosior
        ''')
92
93
    # Let's send one message to one channel and one to the other. Verify they
94
    # were received by the rght listeners.
95
    driver.switch_to.window(windows[1])
96
    execute_in_page(
97
        '''
98 b590eaa2 Wojtek Kosior
        out(sender0, "somebodyoncetoldme", "intheshed");
99
        out(sender0, "worldisgonnarollme", "shewaslooking");
100 58fe4c7d Wojtek Kosior
        ''')
101
102
    driver.switch_to.window(windows[0])
103
    wait_elem_text('d0', 'intheshed')
104
    wait_elem_text('d1', 'shewaslooking')
105
    wait_elem_text('d2', 'intheshed')
106
    wait_elem_text('d2', 'shewaslooking')
107
108
    text = execute_in_page('returnval(divs[0].innerText);')
109
    assert 'shewaslooking' not in text
110
    text = execute_in_page('returnval(divs[1].innerText);')
111
    assert 'intheshed' not in text
112
113
    # Let's create a second sender in third window and use it to send messages
114
    # with the 'prepare' feature.
115
    driver.switch_to.window(windows[2])
116
    execute_in_page(
117
        '''
118 b590eaa2 Wojtek Kosior
        let sender1 = sender_connection();
119
        prepare(sender1, "somebodyoncetoldme", "kindadumb");
120
        out(sender1, "worldisgonnarollme", "withherfinger");
121 58fe4c7d Wojtek Kosior
        ''')
122
123
    driver.switch_to.window(windows[0])
124
    wait_elem_text('d1', 'withherfinger')
125
    text = execute_in_page('returnval(divs[0].innerText);')
126
    assert 'kindadumb' not in text
127
128
    driver.switch_to.window(windows[2])
129 b590eaa2 Wojtek Kosior
    execute_in_page('flush(sender1);')
130 58fe4c7d Wojtek Kosior
131
    driver.switch_to.window(windows[0])
132
    wait_elem_text('d0', 'kindadumb')
133
134
    # Let's verify that prepare()'d messages are properly discarded when
135
    # discard() is called.
136
    driver.switch_to.window(windows[2])
137
    execute_in_page(
138
        '''
139 b590eaa2 Wojtek Kosior
        prepare(sender1, "somebodyoncetoldme", "andherthumb");
140
        discard(sender1);
141
        prepare(sender1, "somebodyoncetoldme", "andhermiddlefinger");
142
        flush(sender1);
143 58fe4c7d Wojtek Kosior
        ''')
144
145
    driver.switch_to.window(windows[0])
146
    wait_elem_text('d0', 'andhermiddlefinger')
147
    text = execute_in_page('returnval(divs[0].innerText);')
148
    assert 'andherthumb' not in text
149
150
    # Let's verify prepare()'d messages are properly auto-flushed when the other
151
    # end of the connection gets killed (e.g. because browser tab gets closed).
152
    driver.switch_to.window(windows[2])
153
    execute_in_page(
154
        '''
155 b590eaa2 Wojtek Kosior
        prepare(sender1, "worldisgonnarollme", "intheshape", 500);
156 58fe4c7d Wojtek Kosior
        ''')
157
    driver.close()
158
159
    driver.switch_to.window(windows[0])
160
    wait_elem_text('d2', 'intheshape')
161
162
    # Verify listener's connection gets closed properly.
163 b590eaa2 Wojtek Kosior
    execute_in_page('close(listener0); close(listener1);')
164 58fe4c7d Wojtek Kosior
165
    driver.switch_to.window(windows[1])
166 b590eaa2 Wojtek Kosior
    execute_in_page('out(sender0, "worldisgonnarollme", "ofanL");')
167
    execute_in_page('out(sender0, "somebodyoncetoldme", "forehead");')
168 58fe4c7d Wojtek Kosior
169
    driver.switch_to.window(windows[0])
170
    wait_elem_text('d2', 'ofanL')
171
    wait_elem_text('d2', 'forehead')
172
    for i in (0, 1):
173
        text = execute_in_page('returnval(divs[arguments[0]].innerText);', i)
174
        assert 'ofanL' not in text
175
        assert 'forehead' not in text