Create tests to run installations on Bare Metal using PiKVM.

This commit is contained in:
Lukas Ruzicka 2023-01-27 14:35:02 +01:00
parent e32cc9ffe3
commit 91ec6e627c
213 changed files with 2259 additions and 3 deletions

61
bis.pl Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/perl
use warnings;
use strict;
use REST::Client;
use JSON::XS;
use Data::Dumper;
my ($variant, $architecture) = @ARGV;
# When no architecture is given, fall back to x86_64.
unless ($architecture) {
$architecture = "x86_64";
}
my $netinst = "";
$variant = ucfirst($variant);
# If $variant is Netinst, then we will correct
# it to Server to get the correct links and then
# use the $netinst later to specify.
if ($variant eq "Netinst") {
$variant = "Server";
$netinst = "Netinst";
}
elsif ($variant eq "Kde") {
$variant = "KDE";
}
print("I am starting the tests for $variant $netinst.\n");
print("Trying to download the iso links.\n");
# Download the JSON file.
my $client = REST::Client->new();
$client->GET('https://openqa.fedoraproject.org/nightlies.json') or die("The iso links could not be downloaded. Exiting.");
print("Iso links downloaded correctly.\n");
my $json = decode_json($client->responseContent());
my $links = [];
# Push the link to $links when a match is found.
for my $iso (@$json) {
if (($iso->{arch} eq $architecture) and (lc($iso->{subvariant}) eq lc($variant))) {
push(@$links, "$iso->{url}");
}
}
my $isolink = $links->[0];
if ($netinst eq "Netinst") {
$isolink = $links->[-1];
}
print("Sending the API command to openQA: \n");
my $command = "openqa-cli api -X POST isos DISTRI=fedora VERSION=Rawhide FLAVOR=PiKVM ARCH=$architecture BUILD=Bare_install_$variant DOWNLOAD=$isolink SUBVARIANT=$variant";
print(" $command\n");
exec($command);

275
lib/pikvm.pm Normal file
View File

@ -0,0 +1,275 @@
package pikvm;
use strict;
use base 'Exporter';
use Exporter;
use lockapi;
use testapi;
use utils;
our @EXPORT = qw(open_pikvm open_subpage power_switch upload_iso_file attach_iso_file detach_iso_file delete_iso_file boot_iso select_stream select_source os_power_off);
# The background virtual machine will open the web browser and will
# point it to the correct address automatically. This routine will
# handle the login into the pikvm web page.
sub open_pikvm {
my $ip_address = get_var("KVM_IP");
# There is a warning that the connection is not safe.
# Make sure we will go past this and proceed to the page
# anyway.
if (check_screen("pikvm_connection_warning", timeout => 20)) {
assert_and_click("pikvm_connection_button_advanced");
assert_and_click("pikvm_connection_link_proceed");
}
# Check that we have reached that destination.
# We prolong the wait time here if there were hiccoughs
# on the network.
assert_screen("pikvm_kvm_login", timeout => 60);
# Login to the PiKVM web administration.
type_very_safely("admin");
sleep(1);
send_key("tab");
sleep(1);
type_very_safely("fedoraftw");
assert_and_click("pikvm_button_login");
assert_screen("pikvm_kvm_welcome_screen");
}
# This routine opens the appropriate subpage
# on the PiKVM main screen. We have not created
# needles for all of the subpages, so if you
# are getting errors, you need to create them.
sub open_subpage {
my $subpage = shift;
# Click on the button in the upper menu
# to open the subpage.
assert_and_click("pikvm_open_$subpage");
assert_screen("pikvm_subpage_opened_$subpage");
}
# This operates the powerswitch and is able to operate
# one of the buttons in a certain way. You can choose
# the $action - short, long, reset. Usually, the short
# press will switch the computer on, the long press
# will switch it off anytime, and reset will reboot it.
sub power_switch {
my $action = shift;
unless ($action) {
$action = "reset";
}
# Click on the icons to open the menu
assert_and_click("pikvm_power_switch");
assert_and_click("pikvm_power_action_$action");
if (check_screen("pikvm_confirmation_ok", timeout => 5)) {
click_lastmatch();
}
}
# This routine will download the $iso from the link
# that is passed via test variables. Note, that downloading
# usually takes some time.
sub upload_iso_file {
my ($iso, $name) = @_;
# Click on the Drive button to access the upload
assert_and_click("pikvm_open_drive");
# If anything is attached, detach it.
if (check_screen("pikvm_drive_attached")) {
assert_and_click("pikvm_drive_disconnect");
}
# Open the Upload dialogue
assert_and_click("pikvm_select_upload_image");
# Check that the Upload dialogue has opened
assert_screen("pikvm_upload_dialogue_opened");
# Click into the URL line has been reached.
assert_and_click("pikvm_url_line");
# Type in the download link
type_very_safely($iso);
# Confirm the Upload with the Upload button
assert_and_click("pikvm_upload_button_upload");
# If the image already exists do nothing and
# confirm the error message.
if (check_screen("pikvm_image_already_exists", timeout => 30)) {
assert_and_click("pikvm_button_ok");
}
else {
# Wait until the upload is complete. With bigger downloads
# the screen went off so we will move the mouse occasionally
# to make sure it will not shut down.
while (check_screen("pikvm_upload_dialogue_opened")) {
mouse_set(500, 500);
sleep(15);
mouse_set(200, 200);
sleep(5);
}
}
# Dismiss the dialogue
assert_and_click("pikvm_open_drive");
}
# This routine will attach the uploaded iso file
# to the PiKVM's drive slot to make it available
# for installations. You can select the $drive
# which would be a "cdrom" or a "flash".
sub attach_iso_file {
my ($name, $drive) = @_;
# Open the Drive menu
assert_and_click("pikvm_open_drive");
# Deattach if anything is left from previous attempts.
if (check_screen("pikvm_drive_attached")) {
assert_and_click("pikvm_drive_disconnect");
}
# Click onto File selector
assert_and_click("pikvm_open_file_selector");
# Select the reqired image
assert_and_click("pikvm_select_iso_$name");
# Select the type
assert_and_click("pikvm_select_type_$drive");
# Attach the iso image
assert_and_click("pikvm_connect_drive_server");
# Check it has been connected
assert_screen("pikvm_drive_attached");
# Dismiss the Drive menu
assert_and_click("pikvm_open_drive");
}
# This routine disconnects the drive from
# the server again. When the drive stays
# connected, sometimes the bare machine stops
# reporting either UEFI or BIOS method to boot
# the machine. Disconnecting the image prevents
# this from happening.
sub detach_iso_file {
assert_and_click("pikvm_open_drive");
assert_and_click("pikvm_drive_disconnect");
assert_screen("pikvm_drive_detached");
assert_and_click("pikvm_open_drive");
}
# This routine deletes the ISO file from the PiKVM's
# disk. We are currently not using this anywhere,
# because deleting the ISO file between two similar
# tests would cost a lot of time to download it again.
sub delete_iso_file {
my $name = shift;
assert_and_click("pikvm_open_drive");
assert_and_click("pikvm_open_file_selector");
assert_and_click("pikvm_select_iso_$name");
assert_and_click("pikvm_drive_button_delete");
assert_and_click("pikvm_confirmation_ok");
assert_screen("pikvm_image_not_selected");
assert_and_click("pikvm_open_drive");
}
# This routine will boot the attached iso image
# in the machine connected to PiKVM. It passes the
# $key to invoke a boot up menu and it then chooses
# the installation source depending on $bootway, which
# can be either "efi" or "bios". If nothing is chosen,
# "efi" will be selected automatically.
sub boot_iso {
my ($key, $bootway) = @_;
my $count = 10;
# As soon as we see this tag, we will send the $key to enter
# the boot selection mode. Note, that if the needle is missing or
# not correct, the system might not be able to select the boot
# source.
if (check_screen("pikvm_boot_devices_select", timeout => 30)) {
send_key($key);
}
# Check that we have reached the boot up menu. Otherwise no need to continue.
assert_screen("pikvm_boot_devices_shown");
# Navigate through the boot devices menu and select the appropriate one.
if ($bootway eq "bios") {
send_key_until_needlematch("pikvm_boot_boot_bios", "down");
}
else {
send_key_until_needlematch("pikvm_boot_boot_uefi", "down");
}
# Confirm the selection using Enter.
send_key("ret");
sleep(5); # To let the VM settle.
# The Grub menu should appear with "Test this media" as a default
# selection. However, we do not want to go with that because the
# check slows down the process. Therefore, we will move one step
# up and select to boot the installer without any testing.
send_key("up");
sleep(1);
send_key("ret");
}
# This routine is similar to boot_iso but it uses different needles
# to identify the sources. Also, it will not send the extra key presses
# to select the correct GRUB entry.
sub select_source {
my ($key, $bootway) = @_;
my $count = 10;
# Start sending the key to enter the boot menu immediately
# after the system starts and repeat for some time.
# Any other, less invasive method was not reliable.
if (check_screen("pikvm_boot_devices_select", timeout => 60)) {
send_key($key);
}
else {die;}
# Check that we have reached the boot up menu.
# Otherwise no need to continue.
assert_screen("pikvm_boot_devices_shown");
# If we have selected BIOS boot, perform it.
# Otherwise do an UEFI boot and select the boot menu
# entry accordingly. Because these early stages do not
# respond to mouse reliably, use keys to navigate
# through the menu.
if ($bootway eq "bios") {
send_key_until_needlematch("pikvm_boot_installed_bios", "down");
}
else {
send_key_until_needlematch("pikvm_boot_installed_uefi", "down");
}
# Confirm the selection using Enter.
send_key("ret");
}
# This routine will power off/logout the running bare metal
# machine from within an installed system.
sub os_power_off {
my $action = shift;
if (check_screen("pikvm_system_off_button")) {
click_lastmatch();
assert_and_click("pikvm_menu_off_button");
if ($action eq "poweroff") {
assert_and_click("pikvm_system_poweroff");
assert_and_click("pikvm_system_poweroff_confirm");
}
elsif ($action eq "logout") {
assert_and_click("pikvm_system_logout");
assert_and_click("pikvm_system_logout_confirm");
}
}
else {
if ($action eq "poweroff") {
enter_cmd("shutdown -h now");
}
elsif ($action eq "logout") {
enter_cmd("logout");
}
}
}
# Set the stream to MPEG or WebRTC.
# PiKVM has two ways to send the screens and this
# will select it. We want to use the MPEG version,
# because it works on Chromium and the needles are
# created using this approach.
sub select_stream {
my $stream = shift;
assert_and_click("pikvm_open_system");
assert_and_click("pikvm_source_$stream");
assert_and_click("pikvm_open_system");
}

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 130,
"width": 28,
"ypos": 182,
"type": "match",
"height": 16,
"match": 80
}
],
"properties": [],
"tags": [
"anaconda_button_done"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 137,
"ypos": 194,
"width": 32,
"height": 14,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"anaconda_button_done"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

View File

@ -0,0 +1,15 @@
{
"area": [
{
"height": 12,
"xpos": 457,
"width": 62,
"type": "match",
"ypos": 384
}
],
"properties": [],
"tags": [
"anaconda_enable_root_account"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 457,
"ypos": 396,
"width": 62,
"height": 12,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"anaconda_enable_root_account"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 16,
"ypos": 385,
"type": "match",
"xpos": 482,
"width": 47,
"match": 85
}
],
"properties": [],
"tags": [
"anaconda_install_options"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 482,
"ypos": 414,
"width": 47,
"height": 16,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"anaconda_install_options"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 32,
"type": "match",
"ypos": 513,
"width": 27,
"xpos": 824,
"match": 90
}
],
"properties": [],
"tags": [
"anaconda_select_root_account"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 440,
"ypos": 650,
"width": 27,
"height": 32,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"anaconda_select_root_account"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 13,
"ypos": 904,
"type": "match",
"xpos": 1061,
"width": 89,
"match": 80
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_begin_installation"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 1051,
"ypos": 938,
"width": 89,
"height": 13,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_begin_installation"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 16,
"type": "match",
"ypos": 921,
"xpos": 1095,
"width": 52,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_continue"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 1088,
"ypos": 956,
"width": 52,
"height": 13,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_continue"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 14,
"width": 53,
"xpos": 1086,
"type": "match",
"ypos": 668,
"match": 85
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_delete_all"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 980,
"ypos": 682,
"width": 53,
"height": 14,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_delete_all"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 139,
"width": 31,
"type": "match",
"ypos": 187,
"height": 16,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_done"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 147,
"ypos": 198,
"width": 31,
"height": 16,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_done"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"type": "match",
"ypos": 922,
"width": 92,
"xpos": 1056,
"height": 14,
"match": 85
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_finish_installation"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 1050,
"ypos": 959,
"width": 65,
"height": 12,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_finish_installation"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 14,
"width": 91,
"xpos": 759,
"type": "match",
"ypos": 710,
"match": 85
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_proceed"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 751,
"ypos": 728,
"width": 91,
"height": 14,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_proceed"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 17,
"width": 68,
"xpos": 794,
"ypos": 695,
"type": "match",
"match": 85
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_reclaim"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"ypos": 779,
"type": "match",
"width": 68,
"xpos": 959,
"height": 17,
"match": 85
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_reclaim"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 786,
"ypos": 700,
"width": 68,
"height": 17,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_button_reclaim"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 148,
"ypos": 168,
"width": 41,
"height": 40,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_icon"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 19,
"type": "match",
"ypos": 229,
"xpos": 430,
"width": 70,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_language"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"ypos": 241,
"type": "match",
"width": 70,
"xpos": 441,
"height": 19,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_language"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 19,
"xpos": 430,
"width": 70,
"ypos": 257,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_language"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 430,
"ypos": 241,
"width": 70,
"height": 19,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_language"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"type": "match",
"ypos": 164,
"xpos": 290,
"width": 161,
"height": 17,
"match": 88
}
],
"properties": [],
"tags": [
"pikvm_anaconda_main_hub"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 290,
"ypos": 164,
"width": 161,
"height": 17,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_main_hub"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 1064,
"ypos": 955,
"width": 35,
"height": 16,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_restart"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 32,
"width": 24,
"xpos": 635,
"type": "match",
"ypos": 514,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_select_destination"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 32,
"xpos": 731,
"width": 24,
"type": "match",
"ypos": 545,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_select_destination"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 827,
"ypos": 424,
"width": 24,
"height": 32,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_anaconda_select_destination"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 501,
"ypos": 683,
"width": 117,
"height": 19,
"type": "match",
"match": 94
}
],
"properties": [],
"tags": [
"pikvm_boot_boot_bios"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 517,
"ypos": 662,
"width": 93,
"height": 16,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_boot_uefi"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 858,
"width": 252,
"type": "match",
"ypos": 955,
"height": 22,
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_devices_select"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 668,
"ypos": 511,
"width": 91,
"height": 15,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_devices_shown"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 521,
"ypos": 619,
"width": 105,
"height": 15,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_installed_bios"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 512,
"ypos": 641,
"width": 60,
"height": 18,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_installed_uefi"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 500,
"ypos": 662,
"width": 123,
"height": 16,
"type": "match",
"match": "93"
}
],
"properties": [],
"tags": [
"pikvm_boot_source_bios"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 519,
"ypos": 621,
"width": 64,
"height": 13,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_source_uefi"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 518,
"ypos": 639,
"width": 92,
"height": 19,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_boot_source_uefi"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 660,
"ypos": 594,
"width": 48,
"height": 17,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_button_login"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 628,
"ypos": 390,
"width": 23,
"height": 20,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_button_ok"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 438,
"ypos": 524,
"width": 57,
"height": 20,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_chrome_started"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 791,
"ypos": 170,
"width": 42,
"height": 16,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_close_browser_confirm"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"height": 20,
"width": 27,
"xpos": 719,
"ypos": 371,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_confirmation_ok"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@ -0,0 +1,16 @@
{
"area": [
{
"xpos": 845,
"ypos": 320,
"width": 97,
"height": 19,
"type": "match",
"match": 90
}
],
"properties": [],
"tags": [
"pikvm_connect_drive_server"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Some files were not shown because too many files have changed in this diff Show More