diff options
author | Wojtek Kosior <koszko@koszko.org> | 2022-02-16 22:01:38 +0100 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2022-02-16 22:01:38 +0100 |
commit | fd9f2fc4783cc606734e61116185c032a63d54a0 (patch) | |
tree | ddc162b1df608c3ae51d74f19fbffc92e5cfc3e3 /test/haketilo_test/unit/test_popup.py | |
parent | 7965f1b455144220c137bcb25c4967283a6b7ff3 (diff) | |
download | browser-extension-fd9f2fc4783cc606734e61116185c032a63d54a0.tar.gz browser-extension-fd9f2fc4783cc606734e61116185c032a63d54a0.zip |
fix out-of-source builds
Diffstat (limited to 'test/haketilo_test/unit/test_popup.py')
-rw-r--r-- | test/haketilo_test/unit/test_popup.py | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/test/haketilo_test/unit/test_popup.py b/test/haketilo_test/unit/test_popup.py new file mode 100644 index 0000000..1fc262c --- /dev/null +++ b/test/haketilo_test/unit/test_popup.py @@ -0,0 +1,257 @@ +# SPDX-License-Identifier: CC0-1.0 + +""" +Haketilo unit tests - repository querying +""" + +# This file is part of Haketilo +# +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# 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 +import json +from selenium.webdriver.support.ui import WebDriverWait + +from ..extension_crafting import ExtraHTML +from ..script_loader import load_script +from .utils import * + +unprivileged_page_info = { + 'url': 'https://example_a.com/something', + 'allow': False +} + +mapping_page_info = { + **unprivileged_page_info, + 'mapping': 'm1', + 'payload': {'identifier': 'res1'} +} + +mocked_page_infos = { + 'privileged': { + 'url': 'moz-extension://<some-id>/file.html', + 'privileged': True + }, + 'blocked_default': unprivileged_page_info, + 'allowed_default': { + **unprivileged_page_info, + 'allow': True + }, + 'blocked_rule': { + **unprivileged_page_info, + 'mapping': '~allow' + }, + 'allowed_rule': { + **unprivileged_page_info, + 'allow': True, + 'mapping': '~allow' + }, + 'mapping': mapping_page_info, + 'error_deciding_policy': { + **mapping_page_info, + 'error': {'haketilo_error_type': 'deciding_policy'} + }, + 'error_missing': { + **mapping_page_info, + 'error': {'haketilo_error_type': 'missing', 'id': 'some-missing-res'} + }, + 'error_circular': { + **mapping_page_info, + 'error': {'haketilo_error_type': 'circular', 'id': 'some-circular-res'} + }, + 'error_db': { + **mapping_page_info, + 'error': {'haketilo_error_type': 'db'} + }, + 'error_other': { + **mapping_page_info, + 'error': {'haketilo_error_type': 'other'} + } +} + +tab_mock_js = ''' +; +const mocked_page_info = (%s)[/#mock_page_info-(.*)$/.exec(document.URL)[1]]; +browser.tabs.sendMessage = async function(tab_id, msg) { + const this_tab_id = (await browser.tabs.getCurrent()).id; + if (tab_id !== this_tab_id) + throw `not current tab id (${tab_id} instead of ${this_tab_id})`; + + if (msg[0] === "page_info") { + return mocked_page_info; + } else if (msg[0] === "repo_query") { + const response = await fetch(msg[1]); + if (!response) + return {error: "Something happened :o"}; + + const result = {ok: response.ok, status: response.status}; + try { + result.json = await response.json(); + } catch(e) { + result.error_json = "" + e; + } + return result; + } else { + throw `bad sendMessage message type: '${msg[0]}'`; + } +} + +const old_tabs_query = browser.tabs.query; +browser.tabs.query = async function(query) { + const tabs = await old_tabs_query(query); + tabs.forEach(t => t.url = mocked_page_info.url); + return tabs; +} +''' % json.dumps(mocked_page_infos) + +popup_ext_data = { + 'background_script': broker_js, + 'extra_html': ExtraHTML( + 'html/popup.html', + { + 'common/browser.js': tab_mock_js, + 'common/indexeddb.js': '; set_repo("https://hydril.la/");' + }, + wrap_into_htmldoc=False + ), + 'navigate_to': 'html/popup.html' +} + +@pytest.mark.ext_data(popup_ext_data) +@pytest.mark.usefixtures('webextension') +@pytest.mark.parametrize('page_info_key', ['', *mocked_page_infos.keys()]) +def test_popup_display(driver, execute_in_page, page_info_key): + """ + Test popup viewing while on a page. Test parametrized with different + possible values of page_info object passed in message from the content + script. + """ + initial_url = driver.current_url + driver.get('about:blank') + driver.get(f'{initial_url}#mock_page_info-{page_info_key}') + + by_id = driver.execute_script( + ''' + const nodes = [...document.querySelectorAll("[id]")]; + const reductor = (ob, node) => Object.assign(ob, {[node.id]: node}); + return nodes.reduce(reductor, {}); + ''') + + if page_info_key == '': + error_msg = 'Page info not avaialable. Try reloading the page.' + error_msg_shown = lambda d: by_id['loading_info'].text == error_msg + WebDriverWait(driver, 10).until(error_msg_shown) + return + + WebDriverWait(driver, 10).until(lambda d: by_id['info_form'].is_displayed()) + assert (page_info_key == 'privileged') == \ + by_id['privileged_page_info'].is_displayed() + assert (page_info_key == 'privileged') ^ \ + by_id['unprivileged_page_info'].is_displayed() + assert by_id['page_url'].text == mocked_page_infos[page_info_key]['url'] + assert not by_id['repo_query_container'].is_displayed() + + if 'allow' in page_info_key: + assert by_id['scripts_blocked'].text.lower() == 'no' + elif page_info_key != 'privileged': + assert by_id['scripts_blocked'].text.lower() == 'yes' + + payload_text = by_id['injected_payload'].text + if page_info_key == 'mapping': + assert payload_text == 'res1' + elif page_info_key == 'error_missing': + assert payload_text == \ + "None (error: resource with id 'some-missing-res' missing from the database)" + elif page_info_key == 'error_circular': + assert payload_text == \ + "None (error: circular dependency of resource with id 'some-circular-res' on itself)" + elif page_info_key == 'error_db': + assert payload_text == \ + 'None (error: failure reading Haketilo internal database)' + elif page_info_key == 'error_other': + assert payload_text == \ + 'None (error: unknown failure occured)' + elif page_info_key != 'privileged': + assert payload_text == 'None' + + mapping_text = by_id['mapping_used'].text + + if page_info_key == 'error_deciding_policy': + assert mapping_text == 'None (error occured when determining policy)' + elif page_info_key == 'mapping' or page_info_key.startswith('error'): + assert mapping_text == 'm1' + + if 'allowed' in page_info_key: + assert 'None (scripts allowed by' in mapping_text + elif 'blocked' in page_info_key: + assert 'None (scripts blocked by' in mapping_text + + if 'rule' in page_info_key: + assert 'by a rule)' in mapping_text + elif 'default' in page_info_key: + assert 'by default policy)' in mapping_text + +@pytest.mark.ext_data(popup_ext_data) +@pytest.mark.usefixtures('webextension') +def test_popup_repo_query(driver, execute_in_page): + """ + Test opening and closing the repo query view in popup. + """ + initial_url = driver.current_url + driver.get('about:blank') + driver.get(f'{initial_url}#mock_page_info-blocked_rule') + + search_but = driver.find_element_by_id("search_resources_but") + WebDriverWait(driver, 10).until(lambda d: search_but.is_displayed()) + search_but.click() + + containers = dict([(name, driver.find_element_by_id(f'{name}_container')) + for name in ('page_info', 'repo_query')]) + assert not containers['page_info'].is_displayed() + assert containers['repo_query'].is_displayed() + shown = lambda d: 'https://hydril.la/' in containers['repo_query'].text + WebDriverWait(driver, 10).until(shown) + + # Click the "Show results" button. + selector = '.repo_query_buttons > button:first-child' + driver.find_element_by_css_selector(selector).click() + shown = lambda d: 'MAPPING_A' in containers['repo_query'].text + WebDriverWait(driver, 10).until(shown) + + # Click the "Cancel" button + selector = '.repo_query_bottom_buttons > button' + driver.find_element_by_css_selector(selector).click() + assert containers['page_info'].is_displayed() + assert not containers['repo_query'].is_displayed() + +@pytest.mark.ext_data(popup_ext_data) +@pytest.mark.usefixtures('webextension') +# Under Parabola's Iceweasel 75 the settings page's window opened during this +# test is impossible to close using driver.close() - it raises an exception with +# message 'closeTab() not supported in iceweasel'. To avoid such error during +# test cleanup, we use the mark below to tell our driver fixture to span a +# separate browser instance for this test. +@pytest.mark.second_driver() +def test_popup_settings_opening(driver, execute_in_page): + """ + Test opening the settings page from popup through button click. + """ + driver.find_element_by_id("settings_but").click() + + first_handle = driver.current_window_handle + WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) == 2) + new_handle = [h for h in driver.window_handles if h != first_handle][0] + + driver.switch_to.window(new_handle) + driver.implicitly_wait(10) + assert "Extension's options page for testing" in \ + driver.find_element_by_tag_name("h1").text |