add playwright test for nextcloud
This commit is contained in:
parent
d13ed1c0ef
commit
f161ab9125
4 changed files with 79 additions and 53 deletions
|
|
@ -91,6 +91,10 @@ let
|
||||||
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']}")
|
||||||
'')
|
'')
|
||||||
|
+ (let
|
||||||
|
script = extraScript args;
|
||||||
|
in
|
||||||
|
lib.optionalString (script != "") script)
|
||||||
+ (optionalString (hasAttr "test" nodes.client && hasAttr "login" nodes.client.test) ''
|
+ (optionalString (hasAttr "test" nodes.client && hasAttr "login" nodes.client.test) ''
|
||||||
with subtest("Login"):
|
with subtest("Login"):
|
||||||
code, logs = client.execute("login_playwright firefox")
|
code, logs = client.execute("login_playwright firefox")
|
||||||
|
|
@ -99,10 +103,6 @@ let
|
||||||
if code != 0:
|
if code != 0:
|
||||||
raise Exception("login_playwright did not succeed")
|
raise Exception("login_playwright did not succeed")
|
||||||
'')
|
'')
|
||||||
+ (let
|
|
||||||
script = extraScript args;
|
|
||||||
in
|
|
||||||
lib.optionalString (script != "") script)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
backupScript = args: (accessScript args).override {
|
backupScript = args: (accessScript args).override {
|
||||||
|
|
@ -153,15 +153,15 @@ in
|
||||||
cfg = config.test.login;
|
cfg = config.test.login;
|
||||||
in {
|
in {
|
||||||
options.test.login = {
|
options.test.login = {
|
||||||
usernameFieldLabel = mkOption {
|
usernameFieldLabelRegex = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "username";
|
default = "username";
|
||||||
};
|
};
|
||||||
passwordFieldLabel = mkOption {
|
passwordFieldLabelRegex = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "password";
|
default = "password";
|
||||||
};
|
};
|
||||||
loginButtonName = mkOption {
|
loginButtonNameRegex = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "login";
|
default = "login";
|
||||||
};
|
};
|
||||||
|
|
@ -234,6 +234,7 @@ in
|
||||||
print(f"Testing for user {u['username']} and password {u['password']}")
|
print(f"Testing for user {u['username']} and password {u['password']}")
|
||||||
|
|
||||||
context = browser.new_context(ignore_https_errors=True)
|
context = browser.new_context(ignore_https_errors=True)
|
||||||
|
context.set_default_navigation_timeout(2 * 60 * 1000)
|
||||||
context.tracing.start(screenshots=True, snapshots=True, sources=True)
|
context.tracing.start(screenshots=True, snapshots=True, sources=True)
|
||||||
try:
|
try:
|
||||||
page = context.new_page()
|
page = context.new_page()
|
||||||
|
|
@ -241,14 +242,14 @@ in
|
||||||
page.goto(testCfg['startUrl'])
|
page.goto(testCfg['startUrl'])
|
||||||
|
|
||||||
if u['username'] is not None:
|
if u['username'] is not None:
|
||||||
print(f"Filling field {testCfg['usernameFieldLabel']} with {u['username']}")
|
print(f"Filling field {testCfg['usernameFieldLabelRegex']} with {u['username']}")
|
||||||
page.get_by_label(testCfg['usernameFieldLabel']).fill(u['username'])
|
page.get_by_label(re.compile(testCfg['usernameFieldLabelRegex'])).fill(u['username'])
|
||||||
if u['password'] is not None:
|
if u['password'] is not None:
|
||||||
print(f"Filling field {testCfg['passwordFieldLabel']} with {u['password']}")
|
print(f"Filling field {testCfg['passwordFieldLabelRegex']} with {u['password']}")
|
||||||
page.get_by_label(testCfg['passwordFieldLabel']).fill(u['password'])
|
page.get_by_label(re.compile(testCfg['passwordFieldLabelRegex'])).fill(u['password'])
|
||||||
|
|
||||||
print(f"Clicking button {testCfg['loginButtonName']}")
|
print(f"Clicking button {testCfg['loginButtonNameRegex']}")
|
||||||
page.get_by_role("button", name=testCfg['loginButtonName']).click()
|
page.get_by_role("button", name=re.compile(testCfg['loginButtonNameRegex'])).click()
|
||||||
|
|
||||||
for line in u['nextPageExpect']:
|
for line in u['nextPageExpect']:
|
||||||
print(f"Running: {line}")
|
print(f"Running: {line}")
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,8 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
test.login = {
|
test.login = {
|
||||||
passwordFieldLabel = "Password";
|
passwordFieldLabelRegex = "Password";
|
||||||
loginButtonName = "Login";
|
loginButtonNameRegex = "Login";
|
||||||
testLoginWith = [
|
testLoginWith = [
|
||||||
{ password = "deluge"; nextPageExpect = [
|
{ password = "deluge"; nextPageExpect = [
|
||||||
"expect(page.get_by_role('button', name='Login')).not_to_be_visible()"
|
"expect(page.get_by_role('button', name='Login')).not_to_be_visible()"
|
||||||
|
|
|
||||||
|
|
@ -80,9 +80,9 @@ let
|
||||||
|
|
||||||
test.login = {
|
test.login = {
|
||||||
startUrl = "http://${config.test.fqdn}/user/login";
|
startUrl = "http://${config.test.fqdn}/user/login";
|
||||||
usernameFieldLabel = "Username or email address";
|
usernameFieldLabelRegex = "Username or email address";
|
||||||
passwordFieldLabel = "Password";
|
passwordFieldLabelRegex = "Password";
|
||||||
loginButtonName = "Sign In";
|
loginButtonNameRegex = "Sign In";
|
||||||
testLoginWith = [
|
testLoginWith = [
|
||||||
{ username = "theadmin"; password = adminPassword + "oops"; nextPageExpect = [
|
{ username = "theadmin"; password = adminPassword + "oops"; nextPageExpect = [
|
||||||
"expect(page.get_by_text('Username or password is incorrect.')).to_be_visible()"
|
"expect(page.get_by_text('Username or password is incorrect.')).to_be_visible()"
|
||||||
|
|
|
||||||
|
|
@ -21,20 +21,9 @@ let
|
||||||
def find_in_logs(unit, text):
|
def find_in_logs(unit, text):
|
||||||
return server.systemctl("status {}".format(unit))[1].find(text) != -1
|
return server.systemctl("status {}".format(unit))[1].find(text) != -1
|
||||||
|
|
||||||
with subtest("cron job succeeds"):
|
with subtest("cron job starts"):
|
||||||
# This calls blocks until the service is done.
|
# This call does not block until the service is done.
|
||||||
server.systemctl("start nextcloud-cron.service")
|
server.succeed("systemctl start nextcloud-cron.service&")
|
||||||
|
|
||||||
# If the service failed, then we're not happy.
|
|
||||||
status = "active"
|
|
||||||
while status == "active":
|
|
||||||
status = server.get_unit_info("nextcloud-cron")["ActiveState"]
|
|
||||||
time.sleep(5)
|
|
||||||
if status != "inactive":
|
|
||||||
raise Exception("Cron job did not finish correctly")
|
|
||||||
|
|
||||||
if not find_in_logs("nextcloud-cron", "nextcloud-cron.service: Deactivated successfully."):
|
|
||||||
raise Exception("Nextcloud cron job did not finish successfully.")
|
|
||||||
|
|
||||||
with subtest("fails with incorrect authentication"):
|
with subtest("fails with incorrect authentication"):
|
||||||
client.fail(
|
client.fail(
|
||||||
|
|
@ -106,10 +95,27 @@ let
|
||||||
)
|
)
|
||||||
if content != "hello\n":
|
if content != "hello\n":
|
||||||
raise Exception("Got incorrect content for file, expected 'hello\n' but got:\n{}".format(content))
|
raise Exception("Got incorrect content for file, expected 'hello\n' but got:\n{}".format(content))
|
||||||
|
|
||||||
|
with subtest("cron job succeeds"):
|
||||||
|
# If the service failed, then we're not happy.
|
||||||
|
status = "active"
|
||||||
|
while status == "active":
|
||||||
|
status = server.get_unit_info("nextcloud-cron")["ActiveState"]
|
||||||
|
time.sleep(5)
|
||||||
|
if status != "inactive":
|
||||||
|
raise Exception("Cron job did not finish correctly")
|
||||||
|
|
||||||
|
if not find_in_logs("nextcloud-cron", "nextcloud-cron.service: Deactivated successfully."):
|
||||||
|
raise Exception("Nextcloud cron job did not finish successfully.")
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
basic = { config, ... }: {
|
basic = { config, ... }: {
|
||||||
|
imports = [
|
||||||
|
testLib.baseModule
|
||||||
|
../../modules/services/nextcloud-server.nix
|
||||||
|
];
|
||||||
|
|
||||||
test = {
|
test = {
|
||||||
subdomain = "n";
|
subdomain = "n";
|
||||||
};
|
};
|
||||||
|
|
@ -136,6 +142,36 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clientLogin = { config, ... }: {
|
||||||
|
imports = [
|
||||||
|
testLib.baseModule
|
||||||
|
testLib.clientLoginModule
|
||||||
|
];
|
||||||
|
virtualisation.memorySize = 4096;
|
||||||
|
|
||||||
|
test = {
|
||||||
|
subdomain = "n";
|
||||||
|
};
|
||||||
|
|
||||||
|
test.login = {
|
||||||
|
startUrl = "http://${config.test.fqdn}";
|
||||||
|
usernameFieldLabelRegex = "[Uu]sername";
|
||||||
|
passwordFieldLabelRegex = "^ *[Pp]assword";
|
||||||
|
loginButtonNameRegex = "[Ll]og [Ii]n";
|
||||||
|
testLoginWith = [
|
||||||
|
{ username = adminUser; password = adminPass; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong username or password')).not_to_be_visible()"
|
||||||
|
"expect(page.get_by_role('button', name=re.compile('[Ll]og [Ii]n'))).not_to_be_visible()"
|
||||||
|
"expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
]; }
|
||||||
|
# Failure is after so we're not throttled too much.
|
||||||
|
{ username = adminUser; password = adminPass + "oops"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong username or password')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
https = { config, ...}: {
|
https = { config, ...}: {
|
||||||
shb.nextcloud = {
|
shb.nextcloud = {
|
||||||
ssl = config.shb.certs.certs.selfsigned.n;
|
ssl = config.shb.certs.certs.selfsigned.n;
|
||||||
|
|
@ -234,10 +270,13 @@ in
|
||||||
basic = pkgs.testers.runNixOSTest {
|
basic = pkgs.testers.runNixOSTest {
|
||||||
name = "nextcloud_basic";
|
name = "nextcloud_basic";
|
||||||
|
|
||||||
|
nodes.client = {
|
||||||
|
imports = [
|
||||||
|
clientLogin
|
||||||
|
];
|
||||||
|
};
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
basic
|
basic
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -252,8 +291,6 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
basic
|
basic
|
||||||
(testLib.backup config.shb.nextcloud.backup)
|
(testLib.backup config.shb.nextcloud.backup)
|
||||||
];
|
];
|
||||||
|
|
@ -269,10 +306,8 @@ in
|
||||||
|
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -288,10 +323,8 @@ in
|
||||||
|
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
previewgenerator
|
previewgenerator
|
||||||
];
|
];
|
||||||
|
|
@ -307,10 +340,8 @@ in
|
||||||
|
|
||||||
nodes.server = {
|
nodes.server = {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
externalstorage
|
externalstorage
|
||||||
];
|
];
|
||||||
|
|
@ -326,10 +357,8 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
testLib.ldap
|
testLib.ldap
|
||||||
ldap
|
ldap
|
||||||
|
|
@ -346,10 +375,8 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
testLib.certs
|
|
||||||
basic
|
basic
|
||||||
|
testLib.certs
|
||||||
https
|
https
|
||||||
testLib.ldap
|
testLib.ldap
|
||||||
ldap
|
ldap
|
||||||
|
|
@ -368,8 +395,6 @@ in
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
testLib.baseModule
|
|
||||||
../../modules/services/nextcloud-server.nix
|
|
||||||
basic
|
basic
|
||||||
prometheus
|
prometheus
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue