#!/usr/bin/perl

use strict;
use X11::GUITest 0.201 qw(StartApp WaitWindowViewable SetInputFocus SendKeys WaitWindowClose);

sub testAppDialog {
	my $app = shift;
	my %args = (
		wname	=> $app,	# window name pattern
		dname	=> 'About',	# dialog name pattern
		dopen	=> '%(h)a',	# Alt-h a (open dialog)
		dclose	=> '%(c)',	# Alt-c (close dialog)
		wclose	=> '%(f)q',	# Alt-f q (close window)
		@_
	);

	# reset keyboard
	use X11::GUITest qw(IsKeyPressed ReleaseKey);
	for my $key (qw( BAC BS BKS BRE CAN CAP DEL DOW END ENT ESC HEL HOM INS
		LEF NUM PGD PGU PRT RIG SCR TAB UP F1 F2 F3 F4 F5 F6 F7 F8 F9
		F10 F11 F12 SPC SPA LSK RSK MNU LSH RSH LCT RCT LAL RAL )) {
		ReleaseKey($key) if IsKeyPressed($key);
	}

	my $pid = StartApp($app);
	$pid and warn "ok 1 # launch $app (pid=$pid)\n"
		or die "unable to launch $app\n";

	local $SIG{__DIE__} = sub { kill TERM => $pid; waitpid $pid, 0; };
		
	my (@win) = WaitWindowViewable($args{wname});
	@win and warn "ok 2 # found $args{wname} window @win\n"
		or die "unable to find $args{wname} window\n";

	my $win = $win[0];
	SetInputFocus($win) and warn "ok 3 # $args{wname} window $win has focus\n"
		or die "unable to set unput focus for $args{wname} window $win\n";

	SendKeys($args{dopen}) and warn "ok 4 # sent $args{dopen}\n"
		or die "unable to send $args{dopen}\n";

	my ($dia) = WaitWindowViewable($args{dname});
	$dia and warn "ok 5 # found $args{dname} dialog $dia\n"
		or die "unable to find $args{dname} dialog\n";

	SetInputFocus($dia) and warn "ok 6 # $args{dname} dialog $dia has focus\n"
		or die "unable to set unput focus for $args{dname} dialog $dia\n";

	SendKeys($args{dclose}) and warn "ok 7 # sent $args{dclose}\n"
		or die "unable to send $args{dclose}\n";

	WaitWindowClose($dia) and warn "ok 8 # $args{dname} dialog $dia closed\n"
		or die "unable to close $args{dname} dialog $dia\n";

	SetInputFocus($win) and warn "ok 9 # $args{wname} window $win has focus\n"
		or die "unable to set unput focus for $args{wname} window $win\n";

	SendKeys($args{wclose}) and warn "ok 10 # sent $args{wclose}\n"
		or die "unable to send $args{wclose}\n";

	WaitWindowClose($win) and warn "ok 11 # $args{wname} window $win closed\n"
		or die "unable to close $args{wname} window $win\n";

	waitpid($pid, 0) == $pid and warn "ok 12 # pid=$pid exited\n"
		or die "unable to terminate pid=$pid\n";

	$? == 0 and warn "ok 13 # exit status 0\n"
		or die "exit status $?\n";

}

die qq(Try "perldoc -F $0"\n)
	if @ARGV == 0 or $ARGV[0] =~ /^-{1,2}h/;

my ($app, %args) = @ARGV;
testAppDialog($app, %args);

__END__

=head1	NAME

test-gui-dialog - simple automated testing of GUI dialogs

=head1	SYNOPSIS

B<test-gui-dialog> I<app> [I<wname> name] [I<dname> name] [I<dopen> keys]
[I<dclose> keys] [I<wclose> keys]

=head1	DESCRIPTION

B<test-gui-dialog> will start application I<app> and wait for application
window I<wname>; it will then open dialog I<dname> by sending keys I<dopen>,
close the dialog by sending keys I<dcolse>, and then will close the application
window by sending keys I<wclose>.

Each step is logged to stderr.  The exit status is zero upon success; otherwise,
the script dies horribly (with non-zero exit status) on the first unsuccessful
step.

=head1	OPTIONS

=over

=item	I<wname> name

Window name pattern; defaults to I<app>.

=item	I<dname> name

Dialog name pattern (default "About").

=item	I<dopen> keys

Key sequence to open dialog (default "%(h)a", i.e. "Alt-h a" for "Help/About").

=item	I<dclose> keys

Key sequence to close dialog (default "%(c)", i.e. "Alt-c" for "Close").

=item	I<wclose> keys

Key sequence to close application window (default "%(f)q", i.e. "Alt-f q" for "File/Quit").

=back

=head1	EXAMPLES

 xvfb-run -a -- test-gui-dialog gedit dclose $'\n'
 xvfb-run -a -- test-gui-dialog gqview

 test-gui-dialog firefox dclose $'\n'
 test-gui-dialog konqueror wclose '%(l)q'

=head1	BUGS

Other I<app> windows are unexpected and can result in an accident.

Running under Xvfb appears to be problematic for certain applications (e.g.
firefox and konqueror).

=head1	SEE ALSO

X11::GUITest, Xvfb(1), xvfb-run

=head1	AUTHOR

Written by Alexey Tourbin <at@altlinux.org>.

=head1	COPYING

Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut
