1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# Copyright (C) 2025 Red Hat, Inc.
#
# SPDX-License-Identifier: LGPL-2.1-or-later
# DIALOG HELPERS
#
# This is a class of dialog helpers. The idea is to instantiate one
# for each test that wants it, maybe like so:
#
#
# def testBasic(self):
# b = self.browser
# d = DialogHelpers(b)
#
# ...
# d.set_TextInput("name.first"), "Jim")
# d.set_TextInput("name.last"), "Kirk")
#
#
# There are helpers for constructing CSS selectors for dialog elements
# such as input fields, helper texts, and the buttons. There are
# helpers for actually interacting with those elements as well.
#
# The fundamental function is this:
#
# - d.id(path, tag)
#
# This constructs the CSS selector for the DOM element that has been
# instantiated with an ID attribute computed by "value.id(tag)", see
# the documentation for the JavaScript dialog framework. The "path"
# parameter describes the way the value handle was derived in
# JavaScript: For top-level ones created by "dlg.value(name)" it is
# just "name". For sub-values created by "value.sub(name_or_index)" it
# is the path of "value" followed by ".", followed by
# "name_or_index". Nothing fancy.
#
# For example,
#
# <input id={dlg.value("name").sub("first").id("input")} />
#
# can be selected in a test like this:
#
# b.set_input_text(d.field("name.first", "input"), "Jim")
#
# There are some functions that encode the guidelines for choosing
# tags. These should be used most of the time:
#
# - d.field(path)
#
# The main input element of a field. Same as d.id(path, "field").
#
# - d.helper_text(path)
#
# The helper text for a field. Same as d.id(path, "helper-text").
#
# The helpers for interacting with elements are called set_TextInput,
# wait_TextInput, set_RadioSelect, etc. They are hopefully easy to
# figure out.
import testlib
def css_escape(x: str) -> str:
return x.replace(".", "\\.")
class DialogHelpers:
def __init__(self, b: testlib.Browser):
self.browser = b
def id(self, path: str, tag: str) -> str:
return f"#dialog-{tag}-{css_escape(path)}"
def field(self, path: str) -> str:
return self.id(path, "field")
def helper_text(self, path: str) -> str:
return self.id(path, "helper-text")
def error(self) -> str:
return "#dialog-error-message"
def apply_button(self) -> str:
return "#dialog-apply"
def cancel_button(self) -> str:
return "#dialog-cancel"
# TextInput
def get_TextInput(self, path: str) -> str:
return self.browser.val(self.field(path))
def wait_TextInput(self, path: str, val: str):
self.browser.wait_val(self.field(path), val)
def set_TextInput(self, path: str, val: str) -> None:
self.browser.set_input_text(self.field(path), val)
# Checkbox
def get_Checkbox(self, path: str) -> bool:
return self.browser.get_checked(self.field(path))
def wait_Checkbox(self, path: str, val: bool) -> None:
# XXX - implemnt Browser.wait_checked and use it here
x = ":checked" if val else ":not(:checked)"
self.browser.wait_visible(self.field(path) + x)
def set_Checkbox(self, path: str, val: bool) -> None:
self.browser.set_checked(self.field(path), val)
# RadioSelect
def get_RadioSelect(self, path: str) -> str:
return self.browser.attr(self.field(path), "data-value")
def wait_RadioSelect(self, path: str, val: str) -> None:
self.browser.wait_attr(self.field(path), "data-value", val)
def set_RadioSelect(self, path: str, val: str) -> None:
self.browser.click(self.id(path, val))
# DropdownSelect
def get_DropdownSelect(self, path: str) -> str:
return self.browser.val(self.field(path))
def wait_DropdownSelect(self, path: str, val: str) -> None:
self.browser.wait_val(self.field(path), val)
def set_DropdownSelect(self, path: str, val: str) -> None:
self.browser.select_from_dropdown(self.field(path), val)
|