aboutsummaryrefslogtreecommitdiff
# SPDX-License-Identifier: CC0-1.0

"""
Haketilo unit tests - showing an error/info/question dalog
"""

# 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

from ..extension_crafting import ExtraHTML
from ..script_loader import load_script

@pytest.mark.ext_data({
    'extra_html': ExtraHTML('html/dialog.html', {}),
    'navigate_to': 'html/dialog.html'
})
@pytest.mark.usefixtures('webextension')
def test_dialog_show_close(driver, execute_in_page):
    """
    A test case of basic dialog showing/closing.
    """
    execute_in_page(load_script('html/dialog.js'))
    buts = execute_in_page(
        '''
        let cb_calls, call_prom;
        const dialog_context = make(() => cb_calls.push("show"),
                                    () => cb_calls.push("hide"));
        document.body.append(dialog_context.main_div);
        const buts = {};
        for (const but of document.getElementsByTagName("button"))
            buts[but.textContent] = but;
        returnval(buts);
        ''')

    for i, (dialog_function, but_text, hidden, expected_result) in enumerate([
            ('info',   'Ok',  ['Yes', 'No'],       None),
            ('error',  'Ok',  ['Yes', 'No'],       None),
            ('error',  None,  ['Yes', 'No'],       None),
            ('loader', None,  ['Yes', 'No', 'Ok'], None),
            ('ask',    'Yes', ['Ok'],              True),
            ('ask',    None,  ['Ok'],              None),
            ('ask',    'No',  ['Ok'],              False)
    ]):
        cb_calls, is_shown = execute_in_page(
            f'''
            cb_calls = [];
            call_prom = {dialog_function}(dialog_context,
                                          `sample_text_${{arguments[0]}}`);
            returnval([cb_calls, dialog_context.shown]);
            ''',
            i)
        assert cb_calls == ['show']
        assert is_shown == True

        page_source = driver.page_source
        assert f'sample_text_{i}' in page_source
        assert f'sample_text_{i - 1}' not in page_source

        # Verify the right buttons are displayed.
        for text, but in buts.items():
            if text in hidden:
                assert not but.is_displayed()
                # Verify clicking a hidden button does nothing.
                execute_in_page('buts[arguments[0]].click();', text)
                assert execute_in_page('returnval(cb_calls);') == cb_calls
            else:
                assert but.is_displayed()

        if but_text is None:
            execute_in_page('close_dialog(dialog_context);')
        else:
            buts[but_text].click()

        cb_calls, result, is_shown = execute_in_page(
            '''{
            const values_cb = r => [cb_calls, r, dialog_context.shown];
            returnval(call_prom.then(values_cb));
            }''')
        assert cb_calls == ['show', 'hide']
        assert result == expected_result
        assert is_shown == False

@pytest.mark.ext_data({
    'extra_html': ExtraHTML('html/dialog.html', {}),
    'navigate_to': 'html/dialog.html'
})
@pytest.mark.usefixtures('webextension')
def test_dialog_queue(driver, execute_in_page):
    """
    A test case of queuing dialog display operations.
    """
    execute_in_page(load_script('html/dialog.js'))
    execute_in_page(
        '''
        let cb_calls = [], call_proms = [];
        const dialog_context = make(() => cb_calls.push("show"),
                                    () => cb_calls.push("hide"));
        document.body.append(dialog_context.main_div);
        ''')

    buts = driver.find_elements_by_tag_name('button')
    buts = dict([(but.text, but) for but in buts])

    for i in range(5):
        cb_calls, is_shown, msg_elem = execute_in_page(
            '''
            call_proms.push(ask(dialog_context, "somequestion" + arguments[0]));
            returnval([cb_calls, dialog_context.shown, dialog_context.msg]);
            ''',
            i)
        assert cb_calls == ['show']
        assert is_shown == True
        assert msg_elem.text == 'somequestion0'

    for i in range(5):
        buts['Yes' if i & 1 else 'No'].click()
        cb_calls, is_shown, msg_elem, result = execute_in_page(
            '''{
            const values_cb =
                r => [cb_calls, dialog_context.shown, dialog_context.msg, r];
            returnval(call_proms.splice(0, 1)[0].then(values_cb));
            }''')
        if i < 4:
            assert cb_calls == ['show']
            assert is_shown == True
            assert msg_elem.text == f'somequestion{i + 1}'
        else:
            assert cb_calls == ['show', 'hide']
            assert is_shown == False

        assert result == bool(i & 1)