Add GNOME Initial Setup post-install test #517

Merged
adamwill merged 25 commits from newtest/gnome-initial-setup into main 2026-05-11 23:55:07 +00:00
64 changed files with 822 additions and 2 deletions

View file

@ -282,6 +282,9 @@ for media_specs in ("43", "44", "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

@ -374,11 +374,16 @@ sub console_loadkeys_us {
if (get_var('LANGUAGE') eq 'french') {
script_run "loqdkeys us", 0;
# might take a few secs
wait_still_screen 3;
wait_still_screen(3);
}
elsif (get_var('LANGUAGE') eq 'japanese' || get_var('LANGUAGE') eq 'turkish') {
script_run "loadkeys us", 0;
wait_still_screen 3;
wait_still_screen(3);
}
elsif (get_var('LANGUAGE') eq 'czech' || get_var('LAYOUT') eq 'czech') {
# Czech uses qwertz by default, so we need to swap y with z
script_run('loadkezs us', 0);
wait_still_screen(3);
}
}

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,19 @@
{
"area": [
{
"width": 234,
"type": "match",
"height": 21,
"ypos": 291,
"xpos": 395,
"click_point": {
"xpos": 117,
"ypos": 10.5
}
}
],
"properties": [],
"tags": [
"gis_button_enable_thirdparty"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 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": 423,
"ypos": 547,
"width": 182,
"type": "match",
"height": 20
}
],
"properties": [],
"tags": [
"gis_button_start_fedora"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 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": [
{
"type": "match",
"height": 26,
"width": 136,
"xpos": 235,
"ypos": 365
}
],
"properties": [],
"tags": [
"gis_field_confirm_password"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 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,19 @@
{
"area": [
{
"xpos": 229,
"ypos": 215,
"click_point": {
"ypos": 18.5,
"xpos": 281
},
"width": 562,
"height": 37,
"type": "match"
}
],
"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,19 @@
{
"area": [
{
"xpos": 234,
"ypos": 222,
"width": 552,
"height": 25,
"type": "match",
"click_point": {
"xpos": 528,
"ypos": 11.5
}
}
],
"properties": [],
"tags": [
"gis_radio_geoservice_disable"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -0,0 +1,19 @@
{
"area": [
{
"xpos": 235,
"ypos": 222,
"click_point": {
"xpos": 528,
"ypos": 11.5
},
"width": 552,
"type": "match",
"height": 25
}
],
"properties": [],
"tags": [
"gis_radio_geoservice_disable"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 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,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": [
{
"type": "match",
"height": 22,
"width": 80,
"xpos": 471,
"ypos": 45
}
],
"properties": [],
"tags": [
"gis_screen_credentials"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 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": [
{
"ypos": 43,
"xpos": 474,
"type": "match",
"height": 21,
"width": 77
}
],
"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": [
{
"width": 73,
"height": 24,
"type": "match",
"ypos": 44,
"xpos": 475
}
],
"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": [
{
"ypos": 44,
"xpos": 422,
"height": 25,
"type": "match",
"width": 181
}
],
"properties": [],
"tags": [
"gis_screen_software"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 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": [
{
"width": 111,
"height": 25,
"type": "match",
"xpos": 459,
"ypos": 44
}
],
"properties": [],
"tags": [
"gis_screen_timezone"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 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": 240,
"ypos": 507,
"width": 251,
"height": 25,
"type": "match"
}
],
"properties": [],
"tags": [
"gis_screen_welcome"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 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

@ -1112,6 +1112,19 @@
"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",
"LAYOUT": "czech",
"POSTINSTALL_PATH": "tests/applications/gnome-initial-setup",
"START_AFTER_TEST": "%DEPLOY_UPLOAD_TEST%"
}
},
"gwenview": {
"profile_groups": {
"kde-all": 40

View file

@ -0,0 +1,35 @@
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");
# 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", timeout => 120);
# closing the user might switch us back to GDM, let's go back there
$self->root_console(tty => 3) if (check_screen 'graphical_login', timeout => 30);
# repeat checking that all processes are terminated, then proceed to delete the user
assert_script_run("(for i in {1..30}; do ! pgrep -u $username >/dev/null && exit 0; sleep 1; done; pgrep -au $username; exit 1)");
assert_script_run("userdel -r $username");
# Reboot the system to trigger GNOME initial setup
enter_cmd("reboot");
}
sub test_flags {
return {fatal => 1};
}
1;
# vim: set sw=4 et:

View file

@ -0,0 +1,185 @@
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.
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',
);
sub get_screen {
# Returns the name of the current screen based on its content.
# Look if we match one of the screens in %tags.
my $matched = check_screen([keys %tags], 10) or die("Unable to determine GNOME Initial Setup screen");
my @matched_tags = @{$matched->{needle}->{tags}};
# Filter only tags we care about
my @known = grep { exists $tags{$_} } @matched_tags;
# Die if we have doubts
die("No known GIS tag in matched needle: @matched_tags") unless @known;
die("Ambiguous GIS screen (multiple matches): @known") if scalar(@known) > 1;
return ($tags{$known[0]});
}
sub handle_welcome {
my $welcome_type = shift;
if ($welcome_type eq "langselect") {
# 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');
set_var('LANGSELECT', '1');
}
else {
assert_and_click('start_setup');
}
}
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", 5)) {
record_soft_failure("Geoservices are not enabled by default which was expected.");
assert_and_click("gis_radio_geoservice_enable");
}
# Disable automatic reporting to test that we can turn options off
assert_and_click("gis_radio_geoservice_disable");
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);
wait_screen_change { send_key("tab"); } 2;
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.
# Also track which screens were visited already.
my $iterations = 0;
my %visited_screens;
my @required_screens = qw(welcome privacy timezone credentials password);
# no software screen on Silverblue
push(@required_screens, 'software') unless (get_var('CANNED'));
while (1) {
die("GNOME Initial Setup appears stuck") if ++$iterations > 20;
my $current_screen = get_screen();
$visited_screens{$current_screen} = 1;
record_info("GNOME Initial Setup", "Testing screen: $current_screen");
last if $current_screen eq 'final';
if ($current_screen eq 'welcome') {
# Welcome can have two types, either it is a language
# setting screen, or it is just a real welcom page.
# Check if we see the "Start Setup" button and in
# that case, click on it, otherwise do the language
# selection.
if (check_screen('start_setup', timeout => 10)) {
handle_welcome('welcome');
}
else {
handle_welcome('langselect');
}
}
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);
}
# Report missing screens
my @missing;
for my $screen (@required_screens) {
unless ($visited_screens{$screen}) {
push(@missing, $screen);
record_info("Screen Check", "GNOME Initial Setup skipped this required screen: $screen");
}
}
die("GNOME Initial Setup skipped required screens: " . join(", ", @missing)) if @missing;
# When we have reached the final screen
assert_and_click("gis_button_start_fedora");
# When we have reached the system, dismiss the tour
handle_welcome_screen();
}
sub test_flags {
return {fatal => 1};
}
1;
# vim: set sw=4 et:

View file

@ -0,0 +1,118 @@
use base "installedtest";
use strict;
use warnings;
use testapi;
use utils;
sub run_as_user {
my ($user, $cmd) = @_;
return script_output("su - $user -c '$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("echo $password | sudo -S -u $user whoami | 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");
# By default, we have not switched languages.
my $locale_check = 0;
# However, if we did, we want to know.
$locale_check = 1 if (get_var('LANGSELECT'));
# Switch to the serial console.
$self->root_console(tty => 3);
assert_script_run("chmod 666 /dev/${serialdev}");
# If locale_check is off, only record info and skip checking.
if ($locale_check == 0) {
record_info("Lang settings", "Language and keyboard layout checks are switched off!");
}
else {
# We have set up a non-US keyboard layout but to run commands successfully,
# we need to load US keyboard layout.
console_loadkeys_us();
# 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
validate_script_output("timedatectl show -p Timezone --value", sub { /Europe\/Bratislava/ }, timeout => 60);
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.
# On Silverblue, there was no screen to set it, so we expect this to be disabled.
if (get_var('CANNED')) {
assert_script_run(q{fedora-third-party query | grep disabled}, timeout => 60);
}
else {
assert_script_run(q{fedora-third-party query | grep enabled}, timeout => 60);
}
# Verify that at least one third-party repository is configured (output is not empty)
assert_script_run(q{fedora-third-party list --csv --columns=name,type | grep -q .});
# Optional extra proof on the DNF side:
unless (get_var('CANNED')) {
assert_script_run(q{dnf repolist --enabled | grep -E 'fedora-cisco-openh264|google-chrome|rpmfusion'});
}
# Check the geolocation service are disabled for the user (the previous test did it)
assert_as_user_eq($user,
q{gsettings get org.gnome.system.location enabled},
'false'
);
# Do not check for keyboard layout and locales because
# this type of setting is currently disabled in G-I-S.
if ($locale_check == 0) {
record_info("Lang settings", "Language and keyboard layout checks are switched off!");
}
else {
# 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
);
}
}
sub test_flags {
return {fatal => 1};
}
1;
# vim: set sw=4 et: