-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
automatic tests for TUI (ncurses) #251
Changes from 7 commits
a2d8479
12c144d
eee00b3
1b27612
1f99889
79c25ff
55a3d2b
b60f2bb
e2fa1a5
89b2eaf
7c7d193
50ba537
c660d1a
12eb453
d3f08eb
387c970
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
------------------------------------------------------------------- | ||
Tue Oct 13 14:42:52 UTC 2020 - Martin Vidner <[email protected]> | ||
|
||
- Add automatic TUI (ncurses) tests using tmux (bsc#1165388). | ||
- 4.3.5 | ||
|
||
------------------------------------------------------------------- | ||
Thu Sep 24 19:46:00 UTC 2020 - [email protected] | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
- `foo.test` - main script of the test case | ||
- `foo.rb` - UI set up |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/bin/sh | ||
|
||
# Test https://bugzilla.suse.com/show_bug.cgi?id=1177760 | ||
# Menu items lose their hotkeys | ||
|
||
set -u # unset variables are an error | ||
MYDIR=$(dirname "$0") | ||
# shellcheck source=/dev/null # that file is checked separately | ||
. "$MYDIR"/tmux-uitest.sh | ||
BUG=1177760 | ||
BASE=menu_hotkeys_$BUG | ||
|
||
tmux_new_session "${MYDIR}/yast_ncurses /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit | ||
trap tmux_cleanup EXIT | ||
|
||
tmux_await "File.*Edit.*View" || exit | ||
sleep 0.1 # draw the rest of the screen | ||
tmux_capture_pane_to "${BASE}-1-initial" | ||
|
||
tmux_send_keys M-V # &View | ||
tmux_capture_pane_to "${BASE}-2-view-menu-activated" | ||
|
||
tmux_send_keys M-N # &Normal | ||
tmux_capture_pane_to "${BASE}-3-normal-menu-item-activated" | ||
|
||
if ! tmux_grep "Last Event"; then | ||
echo "The script does not echo what it should" | ||
exit 1 | ||
fi | ||
|
||
if ! tmux_grep "view_normal"; then | ||
echo "view_normal was not activated, bug boo#$BUG exists" | ||
exit 1 | ||
fi | ||
|
||
tmux_send_keys M-Q # &Quit | ||
exit 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/bin/bash | ||
set -e | ||
set -u | ||
|
||
if ! type -P shellcheck >/dev/null; then | ||
echo "SKIP https://www.shellcheck.net/ is not installed" | ||
exit 0 | ||
fi | ||
|
||
MYDIR=$(dirname "$0") | ||
FILES=("$MYDIR"/*.test "$MYDIR"/tmux-uitest.sh) | ||
shellcheck --wiki-link-count=99 "${FILES[@]}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#!/bin/bash | ||
# tmux-uitest.sh - a shell library to test Text User Interface using tmux | ||
|
||
SESSION=uitest | ||
mvidner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
: "${VERBOSE=false}" | ||
|
||
# $1 shell command for sh -c | ||
tmux_new_session() { | ||
if $VERBOSE; then | ||
echo Starting session | ||
fi | ||
# -s session name | ||
# -x width -y height, | ||
# -d detached | ||
# FIXME: sleep to be able to see errors when running $1 | ||
tmux new-session -s "$SESSION" -x 80 -y 24 -d sh -c "$1; sleep 9999" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lslezak you asked "How can I get more details about the failures?" This sleep lets us capture the screen after a command fails and exits. Tmux has a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ha! Totally intuitive for a beginner... NOT
Found in tmux/tmux#787 |
||
} | ||
|
||
# A --quiet grep | ||
# $1 regex (POSIX ERE) to find in captured pane | ||
# retcode: true or false | ||
tmux_grep() { | ||
local REGEX="$1" | ||
tmux capture-pane -t "$SESSION" -p | grep -E --quiet "$REGEX" | ||
RESULT=("${PIPESTATUS[@]}") | ||
|
||
if [ "${RESULT[0]}" != 0 ]; then | ||
# capturing the pane failed; the session may have exited already | ||
return 2 | ||
fi | ||
|
||
# capturing went fine, pass on the grep result | ||
test "${RESULT[1]}" = 0 | ||
} | ||
|
||
# $1 regex (POSIX ERE) to find in captured pane | ||
tmux_await() { | ||
local REGEX="$1" | ||
|
||
local SLEEPS=(0.1 0.2 0.2 0.5 1 2 2 5) | ||
for SL in "${SLEEPS[@]}"; do | ||
tmux_grep "$REGEX" && return 0 | ||
if [ $? = 2 ]; then return 2; fi # session not found | ||
# text not found, continue waiting for it | ||
sleep "$SL" | ||
done | ||
# text not found, timed out | ||
false | ||
} | ||
|
||
# capture the session to stdout | ||
tmux_capture_pane() { | ||
tmux capture-pane -t "$SESSION" -p | ||
} | ||
|
||
# $1 | ||
# $1.txt plain text | ||
# $1.esc text with escape sequences for colors | ||
tmux_capture_pane_to() { | ||
local OUT="$1" | ||
|
||
# -t target-pane, -p to stdout, | ||
# -e escape sequences for text and background attributes | ||
tmux capture-pane -t "$SESSION" -p -e > "$OUT.esc" | ||
tmux capture-pane -t "$SESSION" -p > "$OUT.txt" | ||
# this is racy. if it is a problem we should make .txt from .esc | ||
# by filtering out the escape sequences | ||
} | ||
|
||
# $1 keys ("C-X" for Ctrl-X, "M-X" for Alt-X, think "Meta"); for details see: | ||
# man tmux | less +/"^KEY BINDINGS" | ||
tmux_send_keys() { | ||
if $VERBOSE; then | ||
echo Sending "$1" | ||
fi | ||
# -t target-pane | ||
tmux send-keys -t "$SESSION" "$1" | ||
} | ||
|
||
# usage: trap tmux_cleanup EXIT | ||
tmux_cleanup() { | ||
if tmux_has_session; then | ||
echo "SCREEN BEGIN (non-empty lines only)" | ||
tmux_capture_pane | grep . | ||
echo "SCREEN END" | ||
tmux_kill_session | ||
fi | ||
} | ||
|
||
# ret code: true or false | ||
tmux_has_session() { | ||
if $VERBOSE; then | ||
echo Detecting the session | ||
fi | ||
# -t target-session | ||
tmux has-session -t "$SESSION" | ||
} | ||
|
||
|
||
tmux_kill_session() { | ||
if $VERBOSE; then | ||
echo Killing the session | ||
fi | ||
# -t target-session | ||
tmux kill-session -t "$SESSION" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#! /usr/bin/env ruby | ||
require_relative "../test_helper" | ||
require "yast" | ||
Yast.ui_component = "ncurses" | ||
load ARGV[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, tests are in tmux which I do not know much, but fine for me. I have other issues:
why it lives in yast2-ruby-bindings? it should be in libyui itself or libyui-bindings if you really want to use ruby and not write it as example program in C++. Do you really expect that libyui contributors search for it here and also run it on their magei/buntu/etc? Ideally it should be
make && make check
in libyui itselfIt tests too late. What happens here? It needs libyui, its bindings, then ycp-ui-bindings, then yast2-core and then yast2-ruby-bindings and then you can see what failed. To be honest I think it will be in comparable speed to get result from openqa itself. It is too slow for unit testing and looks more like full integration testing, where openqa is a better as it test more and has more tests.