#!/usr/bin/python3
# checkpoint:
# 1. osbuild-composer.socket can be started and enabled
# 2. no blueprint by default and can add and delete blueprint
import string
import random
import composerlib
import testlib
@testlib.nondestructive
class TestService(composerlib.ComposerCase):
def setUp(self):
# remove all blueprints
# stop and disable osbuild-composer.socket service
super().setUp()
self.machine.execute("""
for bp in $(composer-cli blueprints list); do
composer-cli blueprints delete $bp
done
systemctl disable --now osbuild-composer.socket
""")
def testBasic(self):
b = self.browser
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
# start and enable osbuild-composer from UI
b.click("button:contains('Start')")
# work around .pf-c-empty-state element disappear in one second
b.wait_in_text("#main", "No Blueprints")
b.wait_text(".pf-c-empty-state h1", "No Blueprints")
# create blueprint with random name and description
name_template = string.ascii_letters + string.digits + "-" + "_"
bp_name = "".join(random.sample(name_template, 20))
desc_template = string.ascii_letters + string.digits + " "
bp_desc = "".join(random.sample(desc_template, 40))
b.click(".pf-c-empty-state button:contains('Create Blueprint')")
b.wait_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# blueprint name
b.set_input_text("#textInput-modal-markup", bp_name)
# blueprint description
b.set_input_text("#textInput2-modal-markup", bp_desc)
# create
b.click("#create-blueprint-modal-create-button")
b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")
# wait for all available compontents visible
with b.wait_timeout(300):
b.wait_present("ul[data-list=inputs]")
# search for openssh-server pacakge
b.set_input_text("#cmpsr-blueprint-input-filter", "openssh-server")
b.key_press("\r")
with b.wait_timeout(120):
b.wait_text("#openssh-server-input", "openssh-server")
# add it to blueprint
b.click("li[data-input=openssh-server] .fa-plus")
# wait for package added
b.wait_present("#blueprint-tabs")
b.wait_present("li[data-component=openssh-server]")
# click commit button
b.click(".cmpsr-header__actions .btn-primary")
# click commit button
b.click("#cmpsr-modal-pending-changes .modal-footer .btn-primary")
b.wait_not_present("#cmpsr-modal-pending-changes")
# wait for toast notification dialog
b.wait_present("#cmpsr-toast-committed .pficon-ok")
# click close button
b.click("#cmpsr-toast-committed .pficon-close")
b.wait_not_present("#cmpsr-toast-committed .pficon-ok")
# click back to blueprint link
b.click("a:contains('Back to Blueprints')")
# new added blueprint should be there with correct name and description
b.wait_visible("li[data-blueprint={}]".format(bp_name))
b.wait_text("#{}-name".format(bp_name), bp_name)
b.wait_text("div[data-description]", bp_desc)
# delete blueprint, cancel first
b.click("#{}-kebab".format(bp_name))
b.wait_attr("#{}-kebab".format(bp_name), "aria-expanded", "true")
b.click("ul[aria-labelledby={}-kebab] a:contains('Delete')".format(bp_name))
b.wait_attr("#{}-kebab".format(bp_name), "aria-expanded", "false")
b.click("#cmpsr-modal-delete button:contains('Cancel')")
b.wait_not_present("#cmpsr-modal-delete")
# delete here
b.click("#{}-kebab".format(bp_name))
b.wait_attr("#{}-kebab".format(bp_name), "aria-expanded", "true")
b.click("ul[aria-labelledby={}-kebab] a:contains('Delete')".format(bp_name))
b.wait_attr("#{}-kebab".format(bp_name), "aria-expanded", "false")
b.click("#cmpsr-modal-delete button:contains('Delete')")
b.wait_not_present("#cmpsr-modal-delete")
b.wait_not_present("li[data-blueprint={}]".format(bp_name))
# no blueprint here
b.wait_in_text("#main", "No Blueprints")
# collect code coverage result
self.check_coverage()
def testNoEnable(self):
b = self.browser
m = self.machine
# stop and disable osbuild-composer.socket
m.execute("systemctl disable --now osbuild-composer.socket")
self.login_and_go("/composer", authorized=True)
b.wait_present("#main")
# do not enable osbuild-composer
b.click(".checkbox input")
# start and enable osbuild-composer from UI
b.click("button:contains('Start')")
# work around .pf-c-empty-state element disappear in one second
b.wait_in_text("#main", "No Blueprints")
b.wait_text(".pf-c-empty-state h1", "No Blueprints")
# osbuild-composer should be disabled
is_enabled = m.execute("systemctl is-enabled osbuild-composer.socket || true").rstrip()
self.assertEqual(is_enabled, "disabled")
# osbuild-composer should be started
is_active = m.execute("systemctl is-active osbuild-composer.socket").rstrip()
self.assertEqual(is_active, "active")
# collect code coverage result
self.check_coverage()
def testNonAdminUser(self):
b = self.browser
m = self.machine
# stop and disable osbuild-composer.socket
m.execute("systemctl disable --now osbuild-composer.socket")
self.login_and_go("/composer", authorized=False)
b.wait_present("#main")
# Start button can be disabled button or clickable button
b.wait_present("button:contains('Start')")
# disable this test due to https://github.com/osbuild/cockpit-composer/issues/941
# if "disabled" not in b.attr("button:contains('Start')", "class"):
# b.click("button:contains('Start')")
# # error message
# b.wait_in_text(".cmpsr-alert-blank-slate", "Not permitted to perform this action.")
# # Start button still there
# b.wait_visible("button:contains('Start')")
# collect code coverage result
self.check_coverage()
if __name__ == '__main__':
testlib.test_main()