Add GNOME Initial Setup post-install test
Some checks failed
CI via Tox and perl / tox (pull_request) Successful in 1m24s
CI via Tox and perl / perl (pull_request) Successful in 3m39s
CI via Tox and perl / checkwiki (pull_request) Failing after 34s

Introduce a new GNOME Initial Setup test suite that resets the existing
user state, runs through the GIS wizard, and verifies that the selected
settings were applied correctly after first login.

The new test covers:
- language selection
- keyboard layout selection
- privacy defaults and toggles
- timezone selection
- third-party repository enablement
- user creation and password setup

Add the required GIS needles, define a new gnome_initial_setup test
scenario in templates.fif.json

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>

Fixes: #506
This commit is contained in:
Lukáš Růžička 2026-03-25 13:26:36 +01:00
commit ab4a2989ac
43 changed files with 627 additions and 0 deletions

View file

@ -281,6 +281,9 @@ for media_specs in ("43", "workstation", "x86_64"):
testtags.append(f"mwriter_select_{media_specs}")
testtags.append(f"mwriter_selected_{media_specs}")
testtags.append("mwriter_mediagroup_official")
# For gnome-initial-setup
for screen in ("credentials", "final", "keyboard", "password", "privacy", "software", "timezone"):
testtags.append(f"gis_screen_{screen}")
# retcode tracker
ret = 0

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 400,
"ypos": 291,
"width": 224,
"height": 21,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_button_enable_thirdparty"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 386,
"ypos": 547,
"width": 106,
"height": 20,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_button_start_fedora"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 233,
"ypos": 365,
"width": 101,
"height": 26,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_field_confirm_password"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 263,
"ypos": 235,
"width": 73,
"height": 24,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_geolocation_bratislava"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -0,0 +1,20 @@
{
"area": [
{
"xpos": 230,
"ypos": 215,
"width": 562,
"height": 37,
"type": "match",
"click_point": {
"xpos": 281,
"ypos": 18.5
},
"match": 90
}
],
"properties": [],
"tags": [
"gis_geoservice_enabled"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 236,
"ypos": 301,
"width": 67,
"height": 31,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_keyboard_layout_czech"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 234,
"ypos": 277,
"width": 68,
"height": 27,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_lang_czech_select"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,20 @@
{
"properties": [],
"tags": [
"gis_radio_geoservice_enable"
],
"area": [
{
"xpos": 232,
"ypos": 217,
"width": 562,
"height": 35,
"type": "match",
"match": "90",
"click_point": {
"xpos": 528,
"ypos": 14
}
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -0,0 +1,20 @@
{
"properties": [],
"tags": [
"gis_radio_reporting_enable"
],
"area": [
{
"xpos": 233,
"ypos": 338,
"width": 556,
"height": 32,
"type": "match",
"match": "90",
"click_point": {
"xpos": 525,
"ypos": 12
}
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 234,
"ypos": 338,
"width": 558,
"height": 31,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"gis_reporting_enabled"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 488,
"ypos": 45,
"width": 47,
"height": 22,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_credentials"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 465,
"ypos": 314,
"width": 93,
"height": 49,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_final"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 489,
"ypos": 42,
"width": 47,
"height": 22,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_keyboard"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 490,
"ypos": 44,
"width": 48,
"height": 21,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_password"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 477,
"ypos": 43,
"width": 73,
"height": 24,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_privacy"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 422,
"ypos": 42,
"width": 181,
"height": 25,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_software"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 457,
"ypos": 43,
"width": 111,
"height": 25,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_timezone"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 473,
"ypos": 41,
"width": 79,
"height": 30,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_welcome"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1,15 @@
{
"area": [
{
"xpos": 960,
"ypos": 44,
"width": 47,
"height": 19,
"type": "match"
}
],
"properties": [],
"tags": [
"next_button"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -1168,6 +1168,18 @@
"START_AFTER_TEST": "%DEPLOY_UPLOAD_TEST%"
}
},
"gnome_initial_setup": {
"profile_groups": {
"workstation-sb-all": 40,
"eln-gnome-lives": 40
},
"settings": {
"BOOTFROM": "c",
"HDD_1": "disk_%FLAVOR%_%MACHINE%.qcow2",
"POSTINSTALL_PATH": "tests/applications/gnome-initial-setup",
"START_AFTER_TEST": "%DEPLOY_UPLOAD_TEST%"
}
},
"gwenview": {
"profile_groups": {
"kde-all": 40

View file

@ -0,0 +1,38 @@
use base "installedtest";
use strict;
use testapi;
use utils;
# This will set up the environment for the GNOME initial setup test.
# It resets the GNOME initial setup state so it will run on next login.
sub run {
my $self = shift;
my $username = get_var("USER_LOGIN") // "test";
# Logout from the Gnome session to end up all user activites.
send_key("super");
wait_still_screen(3);
send_key("ctrl-alt-delete");
assert_and_click("log_out_confirm");
assert_screen("graphical_login");
# Switch to root console
$self->root_console(tty => 3);
# Remove the user clear the system and force the gnome-initial-setup
# to start on new boot.
assert_script_run("loginctl kill-user $username");
assert_script_run("userdel -r $username");
# Reboot the system to trigger GNOME initial setup
type_string("reboot\n");
}
sub test_flags {
return {fatal => 1, milestone => 1};
}
1;
# vim: set sw=4 et:

View file

@ -0,0 +1,152 @@
use base "installedtest";
use strict;
use testapi;
use utils;
# This script walks through the GNOME Initial Setup wizard
# and applies explicit settings needed for later verification
# in follow-up tests. It also checks expected default privacy
# settings during the setup flow.
sub get_screen {
# Returns the name of the current screen based on its content.
my %tags = (
'gis_screen_welcome' => 'welcome',
'gis_screen_keyboard' => 'keyboard',
'gis_screen_privacy' => 'privacy',
'gis_screen_timezone' => 'timezone',
'gis_screen_software' => 'software',
'gis_screen_credentials' => 'credentials',
'gis_screen_password' => 'password',
'gis_screen_final' => 'final',
);
my $matched = check_screen([keys %tags], 10);
for my $tag (@{$matched->{needle}->{tags}}) {
return $tags{$tag} if exists $tags{$tag};
}
die("Unable to determine GNOME Initial Setup screen") unless $matched;
}
sub handle_welcome {
# Select a non-default language explicitely.
type_string('Czech');
wait_still_screen(2);
assert_and_click('gis_lang_czech_select');
assert_and_click('next_button');
}
sub handle_keyboard {
# Select a non-default keyboard layout explicitely.
assert_and_click('gis_keyboard_layout_czech');
assert_and_click('next_button');
}
sub handle_privacy {
# Both options should be on by default.
# If they are not, record a soft-fail and enable them.
unless (check_screen("gis_geoservice_enabled", 2)) {
record_soft_failure("Geoservices are not enabled by default which was expected.");
assert_and_click("gis_radio_geoservice_enable");
}
unless (check_screen("gis_reporting_enabled", 2)) {
record_soft_failure("Autoreporting is not enabled by default which was expected.");
assert_and_click("gis_radio_reporting_enable");
}
assert_and_click("next_button");
}
sub handle_timezone {
# The search field should be focused already
type_string('Bratislava');
wait_still_screen(2);
assert_and_click('gis_geolocation_bratislava');
assert_and_click('next_button');
}
sub handle_software {
# Enable third party repositories for later verification
assert_and_click("gis_button_enable_thirdparty");
assert_and_click("next_button");
}
sub handle_credentials {
my ($realname, $username) = @_;
type_very_safely($realname);
send_key("tab");
wait_still_screen(1);
send_key("ctrl-a");
type_very_safely($username);
assert_and_click("next_button");
}
sub handle_password {
my $password = shift;
type_very_safely($password);
assert_and_click("gis_field_confirm_password");
type_very_safely($password);
assert_and_click("next_button");
}
sub run {
my $self = shift;
# Use explicit non-default account data for later verification.
my $realname = get_var("TESTNAME", "Robin Hood");
my $username = get_var("TESTLOGIN", "rhood");
my $password = get_var("TESTPASSWORD", "nottingham");
assert_screen('gis_screen_welcome', timeout => 120);
# Keep running through screens until we reach the final screen
my $iterations = 0;
while (1) {
die("GNOME Initial Setup appears stuck") if ++$iterations > 20;
my $current_screen = get_screen();
record_info("GNOME Initial Setup", "Testing screen: $current_screen");
last if $current_screen eq 'final';
if ($current_screen eq 'welcome') {
handle_welcome();
}
elsif ($current_screen eq 'keyboard') {
handle_keyboard();
}
elsif ($current_screen eq 'credentials') {
handle_credentials($realname, $username);
}
elsif ($current_screen eq 'password') {
handle_password($password);
}
elsif ($current_screen eq 'privacy') {
handle_privacy();
}
elsif ($current_screen eq 'timezone') {
handle_timezone();
}
elsif ($current_screen eq 'software') {
handle_software();
}
wait_still_screen(2);
}
# When we have reached the final screen
assert_and_click("gis_button_start_fedora");
# When we have reached the system, dismiss the tour
assert_screen("getting_started");
send_key("ret");
wait_still_screen(3);
# System starts with Activities mode, end it
send_key("esc");
}
sub test_flags {
return {fatal => 1, milestone => 1};
}
1;
# vim: set sw=4 et:

View file

@ -0,0 +1,121 @@
use base "installedtest";
use strict;
use warnings;
use testapi;
use utils;
sub assert_cmd_output_eq {
my ($cmd, $expected) = @_;
my $out = script_output($cmd, timeout => 60);
chomp($out);
die("Unexpected output for [$cmd]: got [$out], expected [$expected]") unless $out eq $expected;
}
sub run_as_user {
my ($user, $cmd) = @_;
return script_output(qq{su -l $user -c 'dbus-run-session bash -lc "$cmd"'}, timeout => 60);
}
sub assert_as_user_eq {
my ($user, $cmd, $expected) = @_;
my $out = run_as_user($user, $cmd);
chomp($out);
die("Unexpected user output for [$cmd]: got [$out], expected [$expected]") unless $out eq $expected;
}
sub assert_as_user_matches {
my ($user, $cmd, $regex) = @_;
my $out = run_as_user($user, $cmd);
die("Unexpected user output for [$cmd]: [$out] does not match [$regex]") unless $out =~ $regex;
}
sub assert_password {
# Test the password if it is correct.
my ($user, $password) = @_;
enter_cmd("su - $user"); # Switch to user account to lose admin rights.
# The following command will not show the username without the correct password
my $result = script_run("su - $user -c 'whoami' <<< $password | grep -x $user");
enter_cmd("exit");
return $result;
}
sub run {
my $self = shift;
my $user = get_var("TESTLOGIN", "rhood");
my $password = get_var("TESTPASSWORD", "nottingham");
# Switch to the serial console. To run commands successfully,
# we need to load english keyboard layout. Otherwise, we cannot
# run commands correctly. Note, that the loadkeys command must
# be presented in the foreign layout.
$self->root_console(tty => 3);
enter_cmd('loadkezs us');
wait_still_screen(2);
assert_script_run("chmod 666 /dev/${serialdev}");
# Check that system locale are set to Czech (cs_CZ.UTF-8)
assert_script_run("grep -x 'LANG=cs_CZ.UTF-8' /etc/locale.conf");
assert_script_run("localectl status | grep -E 'System Locale:.*LANG=cs_CZ\.UTF-8'");
assert_script_run('localectl status | grep -E "VC Keymap: cz"');
# Check that the time zone has been set to Bratislave, Europe
assert_cmd_output_eq(q{timedatectl show -p Timezone --value}, 'Europe/Bratislava');
assert_script_run(q{readlink -f /etc/localtime | grep -x '/usr/share/zoneinfo/Europe/Bratislava'});
# Check that user exists and that a correct password is set.
assert_script_run("id $user");
die("The expected password: $password is not valid for user $user.") if (assert_password($user, $password) != 0);
# Check that third party repositories have been enabled.
# FIXME: Workaround, currently we have a bug
# https://bugzilla.redhat.com/show_bug.cgi?id=2446745 and third party repos are not
# enabled, even if clicked in GIS. This will record a soft fail and enable them for now.
# When the bug is gone, we should delete the workaround.
my $result = script_run(q{fedora-third-party query | grep enabled}, timeout => 60);
if ($result != 0) {
record_soft_failure("The third party repositories are not switched on.");
assert_script_run("fedora-third-party enable");
assert_script_run("fedora-third-party query | grep enabled");
}
else {
record_info("Workaround for BZ2446745", "It seems that the bug has been fixed. Edit the test script to disable workaround.");
}
assert_script_run(q{fedora-third-party list --csv --columns=name,type | grep -q .});
# Optional extra proof on the DNF side:
assert_script_run(q{dnf repolist --enabled | grep -E 'fedora-cisco-openh264|google-chrome|rpmfusion'});
# Check the geolocation service are enabled for the user
assert_as_user_eq($user,
q{gsettings get org.gnome.system.location enabled},
'true'
);
# Check that keyboard layout and the locales are correct in user space
assert_as_user_matches($user,
q{gsettings get org.gnome.desktop.input-sources sources},
qr/\('xkb',\s*'cz'\)/
);
assert_as_user_matches($user,
q{locale},
qr/^LANG=cs_CZ\.UTF-8$/m
);
# Check that automatic reporting is enabled.
# This is the most likely key. If this ever fails because the key changed,
# replace it with the exact key confirmed by a one-time gsettings diff.
assert_as_user_eq($user,
q{gsettings get org.gnome.desktop.privacy report-technical-problems},
'true'
);
}
sub test_flags {
return {fatal => 1};
}
1;
# vim: set sw=4 et: