add playwright test for deluge
This commit is contained in:
parent
76d6c246e2
commit
cf3442fb13
2 changed files with 153 additions and 22 deletions
118
test/common.nix
118
test/common.nix
|
|
@ -1,7 +1,7 @@
|
||||||
{ pkgs, lib }:
|
{ pkgs, lib }:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption;
|
inherit (lib) hasAttr mkOption optionalString;
|
||||||
inherit (lib.types) str;
|
inherit (lib.types) bool listOf nullOr submodule str;
|
||||||
|
|
||||||
baseImports = {
|
baseImports = {
|
||||||
imports = [
|
imports = [
|
||||||
|
|
@ -90,8 +90,11 @@ let
|
||||||
raise Exception(f"auth host should be auth.${cfg.domain} but is {response['auth_host']}")
|
raise Exception(f"auth host should be auth.${cfg.domain} but is {response['auth_host']}")
|
||||||
if response['auth_query'] != "rd=${proto_fqdn}/":
|
if response['auth_query'] != "rd=${proto_fqdn}/":
|
||||||
raise Exception(f"auth query should be rd=${proto_fqdn}/ but is {response['auth_query']}")
|
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
|
+ (let
|
||||||
script = extraScript args;
|
script = extraScript args;
|
||||||
in
|
in
|
||||||
|
|
@ -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, ... }: {
|
backup = backupOption: { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
../modules/blocks/restic.nix
|
../modules/blocks/restic.nix
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,12 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
basic = { config, ... }: {
|
basic = { config, ... }: {
|
||||||
|
imports = [
|
||||||
|
testLib.baseModule
|
||||||
|
../../modules/blocks/hardcodedsecret.nix
|
||||||
|
../../modules/services/deluge.nix
|
||||||
|
];
|
||||||
|
|
||||||
test = {
|
test = {
|
||||||
subdomain = "d";
|
subdomain = "d";
|
||||||
};
|
};
|
||||||
|
|
@ -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, ... }: {
|
prometheus = { config, ... }: {
|
||||||
shb.deluge = {
|
shb.deluge = {
|
||||||
prometheusScraperPassword.result = config.shb.hardcodedsecret."scraper".result;
|
prometheusScraperPassword.result = config.shb.hardcodedsecret."scraper".result;
|
||||||
|
|
@ -118,11 +149,13 @@ in
|
||||||
basic = pkgs.testers.runNixOSTest {
|
basic = pkgs.testers.runNixOSTest {
|
||||||
name = "deluge_basic";
|
name = "deluge_basic";
|
||||||
|
|
||||||
|
nodes.client = {
|
||||||
|
imports = [
|
||||||
|
clientLogin
|
||||||
|
];
|
||||||
|
};
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/blocks/hardcodedsecret.nix
|
|
||||||
../../modules/services/deluge.nix
|
|
||||||
basic
|
basic
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -137,9 +170,6 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/blocks/hardcodedsecret.nix
|
|
||||||
../../modules/services/deluge.nix
|
|
||||||
basic
|
basic
|
||||||
(testLib.backup config.shb.deluge.backup)
|
(testLib.backup config.shb.deluge.backup)
|
||||||
];
|
];
|
||||||
|
|
@ -155,11 +185,8 @@ in
|
||||||
|
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/blocks/hardcodedsecret.nix
|
|
||||||
../../modules/services/deluge.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -174,11 +201,8 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/blocks/hardcodedsecret.nix
|
|
||||||
../../modules/services/deluge.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
testLib.ldap
|
testLib.ldap
|
||||||
(testLib.sso config.shb.certs.certs.selfsigned.n)
|
(testLib.sso config.shb.certs.certs.selfsigned.n)
|
||||||
|
|
@ -198,11 +222,8 @@ in
|
||||||
|
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/blocks/hardcodedsecret.nix
|
|
||||||
../../modules/services/deluge.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
prometheus
|
prometheus
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue