starter-kit/test/check-application
Benjamin Graham 0a85319c5e Added search testing
Added test `testSearch`
2020-06-16 22:42:46 -04:00

321 lines
12 KiB
Python
Executable file

#!/usr/bin/python3
# Run this with --help to see available options for tracing and debugging
# See https://github.com/cockpit-project/cockpit/blob/master/test/common/testlib.py
# "class Browser" and "class MachineCase" for the available API.
import os
import sys
# import Cockpit's machinery for test VMs and its browser test API
TEST_DIR = os.path.dirname(__file__)
sys.path.append(os.path.join(TEST_DIR, "common"))
sys.path.append(os.path.join(os.path.dirname(TEST_DIR), "bots/machine"))
from testlib import *
# Test with pre-recorded journal with tlog UID 981
class TestApplication(MachineCase):
def _login(self):
self.login_and_go("/session-recording")
b = self.browser
m = self.machine
b.wait_present(".content-header-extra")
b.wait_present("#user")
return b, m
def _sel_rec(self, cond=":first()"):
self.browser.click(f".listing-ct-item{cond}")
def _term_line(self, lineno):
return f".xterm-accessibility-tree div:nth-child({lineno})"
def testPlay(self):
b, _ = self._login()
self._sel_rec()
b.click("#player-play-pause")
b.wait_in_text(self._term_line(1), "localhost")
def testFastforwardControls(self):
slider = ".slider > .min-slider-handle"
b, _ = self._login()
self._sel_rec()
# fast forward
b.click("#player-fast-forward")
b.wait_in_text(self._term_line(12), "exit")
b.wait_attr(slider, "style", "left: 100%;")
# test restart playback
b.click("#player-restart")
b.wait_text(self._term_line(1), "Blank line")
b.wait_attr(slider, "style", "left: 100%;")
def testSpeedControls(self):
b, _ = self._login()
self._sel_rec()
# increase speed
b.wait_present("#player-speed-up")
b.click("#player-speed-up")
b.wait_present("#player-speed")
b.wait_text("#player-speed", "x2")
b.click("#player-speed-up")
b.wait_text("#player-speed", "x4")
b.click("#player-speed-up")
b.wait_text("#player-speed", "x8")
b.click("#player-speed-up")
b.wait_text("#player-speed", "x16")
# decrease speed
b.click("#player-speed-down")
b.wait_text("#player-speed", "x8")
b.click("#player-speed-down")
b.wait_text("#player-speed", "x4")
b.click("#player-speed-down")
b.wait_text("#player-speed", "x2")
b.click("#player-speed-down")
b.wait_present("#player-speed")
b.click("#player-speed-down")
b.wait_text("#player-speed", "/2")
b.click("#player-speed-down")
b.wait_text("#player-speed", "/4")
b.click("#player-speed-down")
b.wait_text("#player-speed", "/8")
b.click("#player-speed-down")
b.wait_text("#player-speed", "/16")
# restore speed
b.click("#player-speed-reset")
b.wait_present("#player-speed")
b.click("#player-speed-down")
b.wait_text("#player-speed", "/2")
def testZoomControls(self):
default_scale_sel = '.console-ct[style^="transform: scale(1)"]'
zoom_one_scale_sel = '.console-ct[style^="transform: scale(1.1)"]'
zoom_two_scale_sel = '.console-ct[style^="transform: scale(1.2)"]'
zoom_three_scale_sel = '.console-ct[style^="transform: scale(1.3)"]'
zoom_fit_to = (
'.console-ct[style*="translate(-50%, -50%)"]'
'[style*="top: 50%"]'
'[style*="left: 50%"]'
)
b, _ = self._login()
self._sel_rec()
# Wait for terminal with scale(1)
b.wait_present(default_scale_sel)
# Zoom in x3
b.click("#player-zoom-in")
b.wait_present(zoom_one_scale_sel)
b.click("#player-zoom-in")
b.wait_present(zoom_two_scale_sel)
b.click("#player-zoom-in")
b.wait_present(zoom_three_scale_sel)
# Zoom Out
b.click("#player-zoom-out")
b.wait_present(zoom_two_scale_sel)
# Fit zoom to screen
b.click("#player-fit-to")
b.wait_present(zoom_fit_to)
def testSkipFrame(self):
b, _ = self._login()
self._sel_rec()
b.wait_present(self._term_line(1))
# loop until 3 valid frames have passed
while "localhost" not in b.text(self._term_line(1)):
b.click("#player-skip-frame")
b.wait_in_text(self._term_line(1), "localhost")
def testPlaybackPause(self):
import time
b, _ = self._login()
self._sel_rec()
# Start and pause the player
b.click("#player-restart")
b.click("#player-play-pause")
b.click("#player-play-pause")
time.sleep(10)
# Make sure it didn't keep playing
b.wait_not_in_text(self._term_line(1), "whoami")
# Test if it can start playing again
b.click("#player-play-pause")
def testSessionRecordingConf(self):
import json, configparser
b, m = self._login()
# Ensure that the button leads to the config page
b.click("#btn-config")
b.enter_page("/session-recording/config")
# TLOG config
conf_file_path = "/etc/tlog/"
conf_file = f"{conf_file_path}tlog-rec-session.conf"
save_file = "/tmp/tlog-rec-session.conf"
test_file = "/tmp/test-tlog-rec-session.conf"
# Save the existing config
b.click("#btn-save-tlog-conf")
m.download(conf_file, save_file)
# Change all of the fields
b.set_input_text("#shell", "/test/path/shell")
b.set_input_text("#notice", "Test Notice")
b.set_input_text("#latency", "1")
b.set_input_text("#payload", "2")
b.set_checked("#log_input", True)
b.set_checked("#log_output", False)
b.set_checked("#log_window", False)
b.set_input_text("#limit_rate", "3")
b.set_input_text("#limit_burst", "4")
b.set_val("#limit_action", "drop")
b.set_input_text("#file_path", "/test/path/file")
b.set_input_text("#syslog_facility", "testfac")
b.set_val("#syslog_priority", "info")
b.set_val("#journal_priority", "info")
b.set_checked("#journal_augment", False)
b.set_val("#writer", "file")
b.click("#btn-save-tlog-conf")
m.download(conf_file, test_file)
# Revert to the previous config before testing to ensure test continuity
m.upload([save_file], conf_file_path)
# Check that the config reflects the changes
conf = json.load(open(test_file, "r"))
assert json.dumps(conf) == json.dumps(
{
"shell": "/test/path/shell",
"notice": "Test Notice",
"latency": 1,
"payload": 2,
"log": {"input": True, "output": False, "window": False},
"limit": {"rate": 3, "burst": 4, "action": "drop"},
"file": {"path": "/test/path/file"},
"syslog": {"facility": "testfac", "priority": "info"},
"journal": {"priority": "info", "augment": False},
"writer": "file",
}
)
# SSSD config
conf_file_path = "/etc/sssd/conf.d/"
conf_file = f"{conf_file_path}sssd-session-recording.conf"
save_file = "/tmp/sssd-session-recording.conf"
test_none_file = "/tmp/test-none-sssd-session-recording.conf"
test_some_file = "/tmp/test-some-sssd-session-recording.conf"
test_all_file = "/tmp/test-all-sssd-session-recording.conf"
# Save the existing config
b.click("#btn-save-sssd-conf")
m.download(conf_file, save_file)
# Download test with scope 'None'
b.set_val("#scope", "none")
b.click("#btn-save-sssd-conf")
m.download(conf_file, test_none_file)
# Download test with scope 'Some'
b.set_val("#scope", "some")
b.set_input_text("#users", "test users")
b.set_input_text("#groups", "test groups")
b.click("#btn-save-sssd-conf")
m.download(conf_file, test_some_file)
# Download test with scope 'All'
b.set_val("#scope", "all")
b.click("#btn-save-sssd-conf")
m.download(conf_file, test_all_file)
# Revert to the previous config before testing to ensure test continuity
m.upload([save_file], conf_file_path)
# Check that the configs reflected the changes
conf = configparser.ConfigParser()
conf.read_file(open(test_none_file, "r"))
assert conf["session_recording"]["scope"] == "none"
conf.read_file(open(test_some_file, "r"))
assert conf["session_recording"]["scope"] == "some"
assert conf["session_recording"]["users"] == "test users"
assert conf["session_recording"]["groups"] == "test groups"
conf.read_file(open(test_all_file, "r"))
assert conf["session_recording"]["scope"] == "all"
def testDisplayDrag(self):
b, _ = self._login()
self._sel_rec()
# start playback and pause in middle
b.click("#player-play-pause")
b.wait_in_text(self._term_line(1), "localhost")
b.click("#player-play-pause")
# zoom in so that the whole screen is no longer visible
b.click("#player-zoom-in")
b.click("#player-zoom-in")
# select and ensure drag'n'pan mode
b.click("#player-drag-pan")
b.wait_present(".fa-hand-rock-o")
# scroll and check for screen movement
b.mouse(".dragnpan", "mousedown", 200, 200)
b.mouse(".dragnpan", "mousemove", 10, 10)
assert b.attr(".dragnpan", "scrollTop") != 0
assert b.attr(".dragnpan", "scrollLeft") != 0
def testLogCorrelation(self):
b, _ = self._login()
# select the recording with the extra logs
self._sel_rec(":contains('01:07')")
b.click("#btn-logs-view")
# fast forward until the end
while "exit" not in b.text(self._term_line(22)):
b.click("#player-skip-frame")
# check for extra log entries
b.wait_present(".cockpit-log-message:contains('authentication failure')")
def testZoomSpeedControls(self):
default_scale_sel = '.console-ct[style^="transform: scale(1)"]'
play_scale_sel = '.console-ct[style^="transform: scale(0.4"]'
zoom_one_scale_sel = '.console-ct[style^="transform: scale(0.5"]'
b, _ = self._login()
self._sel_rec()
# set speed x16 and begin playing, expecting a size adjustment
for _ in range(4):
b.click("#player-speed-up")
b.wait_present(default_scale_sel)
b.click("#player-play-pause")
b.wait_present(play_scale_sel)
# wait until sleeping and zoom in
b.wait_in_text(self._term_line(8), "sleep")
b.click("#player-zoom-in")
b.wait_present(zoom_one_scale_sel)
# zoom out while typing fast
b.wait_in_text(self._term_line(9), "localhost")
b.click("#player-zoom-out")
b.wait_present(play_scale_sel)
def testSearch(self):
import time
b, _ = self._login()
# conduct searches that will return 2, 1, or 0 items
terms = {
0: {
"this should return nothing",
"this should also return nothing",
"0123456789",
},
1: {
"extra commands",
"whoami",
"ssh",
"thisisatest123",
"thisisanothertest456",
},
2: {
"id",
"contractor1",
"localhost",
"exit",
"actor",
"contractor1@localhost",
},
}
for num in terms:
for term in terms[num]:
# enter the search term and wait for results to return
b.set_input_text("#recording-search", term)
time.sleep(0.5)
assert b.text(".listing-ct").count("contractor1") == num
if __name__ == "__main__":
test_main()