Skip to content

Commit

Permalink
add playwright test for deluge
Browse files Browse the repository at this point in the history
  • Loading branch information
ibizaman authored and ibizaman committed Jan 26, 2025
1 parent 76d6c24 commit cf3442f
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 22 deletions.
118 changes: 114 additions & 4 deletions test/common.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{ pkgs, lib }:
let
inherit (lib) mkOption;
inherit (lib.types) str;
inherit (lib) hasAttr mkOption optionalString;
inherit (lib.types) bool listOf nullOr submodule str;

baseImports = {
imports = [
Expand Down Expand Up @@ -90,8 +90,11 @@ let
raise Exception(f"auth host should be auth.${cfg.domain} but is {response['auth_host']}")
if response['auth_query'] != "rd=${proto_fqdn}/":
raise Exception(f"auth query should be rd=${proto_fqdn}/ but is {response['auth_query']}")
''
)
'')
+ (optionalString (hasAttr "test" nodes.client && hasAttr "login" nodes.client.test) ''
with subtest("Login"):
print(client.succeed("login_playwright firefox"))
'')
+ (let
script = extraScript args;
in
Expand Down Expand Up @@ -142,6 +145,113 @@ in
};
};

clientLoginModule = { config, pkgs, ... }: let
cfg = config.test.login;
in {
options.test.login = {
usernameFieldLabel = mkOption {
type = str;
default = "username";
};
passwordFieldLabel = mkOption {
type = str;
default = "password";
};
loginButtonName = mkOption {
type = str;
default = "login";
};
testLoginWith = mkOption {
type = listOf (submodule {
options = {
username = mkOption {
type = nullOr str;
default = null;
};
password = mkOption {
type = nullOr str;
default = null;
};
nextPageExpect = mkOption {
type = listOf str;
};
};
});
};
startUrl = mkOption {
type = str;
default = "http://${config.test.fqdn}";
};
};
config = {
networking.hosts = {
"192.168.1.2" = [ config.test.fqdn ];
};

environment.variables = {
PLAYWRIGHT_BROWSERS_PATH = pkgs.playwright-driver.browsers;
};

environment.systemPackages = [
(pkgs.writers.writePython3Bin "login_playwright"
{
libraries = [ pkgs.python3Packages.playwright ];
flakeIgnore = [ "F401" "E501" ];
}
(let
testCfg = pkgs.writeText "users.json" (builtins.toJSON cfg);
in ''
# import re
import json
import sys
from playwright.sync_api import expect
from playwright.sync_api import sync_playwright
browsers = {
"chromium": ["--headless", "--disable-gpu"],
"firefox": [],
"webkit": []
}
if len(sys.argv) != 2 or sys.argv[1] not in browsers.keys():
print(f"usage: {sys.argv[0]} [{'|'.join(browsers.keys())}]")
sys.exit(1)
browser_name = sys.argv[1]
browser_args = browsers.get(browser_name)
print(f"Running test on {browser_name} {' '.join(browser_args)}")
with open("${testCfg}") as f:
testCfg = json.load(f)
with sync_playwright() as p:
browser = getattr(p, browser_name).launch(args=browser_args)
for u in testCfg["testLoginWith"]:
print(f"Testing for user {u['username']} and password {u['password']}")
context = browser.new_context(ignore_https_errors=True)
context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = context.new_page()
page.goto(testCfg['startUrl'])
page.screenshot(path="example.png")
if u['username'] is not None:
page.get_by_label(testCfg['usernameFieldLabel']).fill(u['username'])
if u['password'] is not None:
page.get_by_label(testCfg['passwordFieldLabel']).fill(u['password'])
page.get_by_role("button", name=testCfg['loginButtonName']).click()
for line in u['nextPageExpect']:
eval(line)
context.tracing.stop(path="trace.zip")
browser.close()
'')
)
];
};
};

backup = backupOption: { config, ... }: {
imports = [
../modules/blocks/restic.nix
Expand Down
57 changes: 39 additions & 18 deletions test/services/deluge.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ let
'';

basic = { config, ... }: {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
];

test = {
subdomain = "d";
};
Expand All @@ -92,6 +98,31 @@ let
};
};

clientLogin = { config, ... }: {
imports = [
testLib.baseModule
testLib.clientLoginModule
];
test = {
subdomain = "d";
};

test.login = {
passwordFieldLabel = "Password";
loginButtonName = "Login";
testLoginWith = [
{ password = "deluge"; nextPageExpect = [
"expect(page.get_by_role('button', name='Login')).not_to_be_visible()"
"expect(page.get_by_text('Login Failed')).not_to_be_visible()"
]; }
{ password = "other"; nextPageExpect = [
"expect(page.get_by_role('button', name='Login')).to_be_visible()"
"expect(page.get_by_text('Login Failed')).to_be_visible()"
]; }
];
};
};

prometheus = { config, ... }: {
shb.deluge = {
prometheusScraperPassword.result = config.shb.hardcodedsecret."scraper".result;
Expand All @@ -118,11 +149,13 @@ in
basic = pkgs.testers.runNixOSTest {
name = "deluge_basic";

nodes.client = {
imports = [
clientLogin
];
};
nodes.server = {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
basic
];
};
Expand All @@ -137,9 +170,6 @@ in

nodes.server = { config, ... }: {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
basic
(testLib.backup config.shb.deluge.backup)
];
Expand All @@ -155,11 +185,8 @@ in

nodes.server = {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
testLib.certs
basic
testLib.certs
https
];
};
Expand All @@ -174,11 +201,8 @@ in

nodes.server = { config, ... }: {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
testLib.certs
basic
testLib.certs
https
testLib.ldap
(testLib.sso config.shb.certs.certs.selfsigned.n)
Expand All @@ -198,11 +222,8 @@ in

nodes.server = {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/services/deluge.nix
testLib.certs
basic
testLib.certs
https
prometheus
];
Expand Down

0 comments on commit cf3442f

Please sign in to comment.